Merge branch 'next' into issue-569

Conflicts:
	cronjobs/findblock.php
This commit is contained in:
Sebastian Grewe 2013-08-19 09:37:54 +02:00
commit 408ebf3b0b
30 changed files with 250 additions and 131 deletions

View File

@ -96,3 +96,18 @@ Small Time Miners are running various stratum only pools for different coins.
| -------- | ---- | ------------: | ------------------: | ----- | | -------- | ---- | ------------: | ------------------: | ----- |
| http://www.litecoinfor.me | Litecoin | 0 | 0 | | | http://www.litecoinfor.me | Litecoin | 0 | 0 | |
| http://www.fastcoinfor.me | Fastcoin | 0.830 MHash | 2 | | | http://www.fastcoinfor.me | Fastcoin | 0.830 MHash | 2 | |
### ZC
| Pool URL | Coin | Avg. Hashrate | Avg. Active Workers | Notes |
| -------- | ---- | ------------: | ------------------: | ----- |
| https://ltc.hashfaster.com | LTC | 70 MHash | 80 | Custom Template |
### nutnut
| Pool URL | Coin | Avg. Hashrate | Avg. Active Workers | Notes |
| -------- | ---- | ------------: | ------------------: | ----- |
| http://ftc.nut2pools.com | Feathercoin | 45-50Mhs | 25 workers | New style, PPLNS |
| http://wdc.nut2pools.com | Worldcoin | 3.5 Mhs | 3 workers | New style, PPLNS |
| http://pxc.nut2pools.com | Phenixcoin | 0 | 0 | New style | PPLNS |

View File

@ -70,7 +70,7 @@ if (! empty($users)) {
// Send balance, fees are reduced later by RPC Server // Send balance, fees are reduced later by RPC Server
try { try {
$bitcoin->sendtoaddress($aUserData['coin_address'], $dBalance); $bitcoin->sendtoaddress($aUserData['coin_address'], $dBalance - $config['txfee']);
} catch (BitcoinClientException $e) { } catch (BitcoinClientException $e) {
$log->logError('Failed to send requested balance to coin address, please check payout process'); $log->logError('Failed to send requested balance to coin address, please check payout process');
continue; continue;

View File

@ -62,7 +62,7 @@ if (count($aPayouts) > 0) {
continue; continue;
} }
try { try {
$bitcoin->sendtoaddress($aData['coin_address'], $dBalance); $bitcoin->sendtoaddress($aData['coin_address'], $dBalance - $config['txfee']);
} catch (BitcoinClientException $e) { } catch (BitcoinClientException $e) {
$log->logError('Failed to send requested balance to coin address, please check payout process'); $log->logError('Failed to send requested balance to coin address, please check payout process');
continue; continue;

View File

@ -58,7 +58,7 @@ if (!empty($aNotifications)) {
$aData = json_decode($aNotification['data'], true); $aData = json_decode($aNotification['data'], true);
$aWorker = $worker->getWorker($aData['id']); $aWorker = $worker->getWorker($aData['id']);
$log->logInfo(" " . $aWorker['username'] . " ..."); $log->logInfo(" " . $aWorker['username'] . " ...");
if ($aWorker['active'] == 1) { if ($aWorker['hashrate'] > 0) {
if ($notification->setInactive($aNotification['id'])) { if ($notification->setInactive($aNotification['id'])) {
$log->logInfo(" updated #" . $aNotification['id'] . " for " . $aWorker['username'] . " as inactive\n"); $log->logInfo(" updated #" . $aNotification['id'] . " for " . $aWorker['username'] . " as inactive\n");
} else { } else {

View File

@ -73,6 +73,8 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
$monitoring->setStatus($cron_name . "_status", "okerror", 1); $monitoring->setStatus($cron_name . "_status", "okerror", 1);
exit(1); exit(1);
} }
$log->logInfo('Adjusting round target to PPLNS target ' . $pplns_target);
$iRoundShares = $pplns_target;
} else { } else {
$log->logDebug("Not able to match PPLNS target of $pplns_target with $iRoundShares"); $log->logDebug("Not able to match PPLNS target of $pplns_target with $iRoundShares");
// We need to fill up with archived shares // We need to fill up with archived shares
@ -124,26 +126,26 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
// Loop through all accounts that have found shares for this round // Loop through all accounts that have found shares for this round
foreach ($aAccountShares as $key => $aData) { foreach ($aAccountShares as $key => $aData) {
// Payout based on PPLNS target shares, proportional payout for all users // Payout based on PPLNS target shares, proportional payout for all users
$aData['percentage'] = number_format(round(( 100 / $iRoundShares) * $aData['valid'], 8), 8); $aData['percentage'] = round(( 100 / $iRoundShares) * $aData['valid'], 8);
$aData['payout'] = number_format(round(( $aData['percentage'] / 100 ) * $dReward, 8), 8); $aData['payout'] = round(( $aData['percentage'] / 100 ) * $dReward, 8);
// Defaults // Defaults
$aData['fee' ] = 0; $aData['fee' ] = 0;
$aData['donation'] = 0; $aData['donation'] = 0;
if ($config['fees'] > 0 && $aData['no_fees'] == 0) if ($config['fees'] > 0 && $aData['no_fees'] == 0)
$aData['fee'] = number_format(round($config['fees'] / 100 * $aData['payout'], 8), 8); $aData['fee'] = round($config['fees'] / 100 * $aData['payout'], 8);
// Calculate donation amount, fees not included // Calculate donation amount, fees not included
$aData['donation'] = number_format(round($user->getDonatePercent($user->getUserId($aData['username'])) / 100 * ( $aData['payout'] - $aData['fee']), 8), 8); $aData['donation'] = round($user->getDonatePercent($user->getUserId($aData['username'])) / 100 * ( $aData['payout'] - $aData['fee']), 8);
// Verbose output of this users calculations // Verbose output of this users calculations
$log->logInfo($aData['id'] . "\t" . $log->logInfo($aData['id'] . "\t" .
$aData['username'] . "\t" . $aData['username'] . "\t" .
$aData['valid'] . "\t" . $aData['valid'] . "\t" .
$aData['invalid'] . "\t" . $aData['invalid'] . "\t" .
$aData['percentage'] . "\t" . number_format($aData['percentage'], 8) . "\t" .
$aData['payout'] . "\t" . number_format($aData['payout'], 8) . "\t" .
$aData['donation'] . "\t" . number_format($aData['donation'], 8) . "\t" .
$aData['fee']); number_format($aData['fee'], 8));
// Add full round share statistics, not just PPLNS // Add full round share statistics, not just PPLNS
foreach ($aRoundAccountShares as $key => $aRoundData) { foreach ($aRoundAccountShares as $key => $aRoundData) {

View File

@ -44,13 +44,13 @@ if ( $bitcoin->can_connect() === true ){
// Value per share calculation // Value per share calculation
if ($config['reward_type'] != 'block') { if ($config['reward_type'] != 'block') {
$pps_value = number_format(round($config['reward'] / (pow(2,32) * $dDifficulty) * pow(2, $config['difficulty']), 12) ,12); $pps_value = round($config['reward'] / (pow(2,32) * $dDifficulty) * pow(2, $config['difficulty']), 12);
} else { } else {
// Try to find the last block value and use that for future payouts, revert to fixed reward if none found // Try to find the last block value and use that for future payouts, revert to fixed reward if none found
if ($aLastBlock = $block->getLast()) { if ($aLastBlock = $block->getLast()) {
$pps_value = number_format(round($aLastBlock['amount'] / (pow(2,32) * $dDifficulty) * pow(2, $config['difficulty']), 12) ,12); $pps_value = round($aLastBlock['amount'] / (pow(2,32) * $dDifficulty) * pow(2, $config['difficulty']), 12);
} else { } else {
$pps_value = number_format(round($config['reward'] / (pow(2,32) * $dDifficulty) * pow(2, $config['difficulty']), 12) ,12); $pps_value = round($config['reward'] / (pow(2,32) * $dDifficulty) * pow(2, $config['difficulty']), 12);
} }
} }
@ -65,7 +65,7 @@ $log->logInfo("ID\tUsername\tInvalid\tValid\t\tPPS Value\t\tPayout\t\tDonation\t
foreach ($aAccountShares as $aData) { foreach ($aAccountShares as $aData) {
// Take our valid shares and multiply by per share value // Take our valid shares and multiply by per share value
$aData['payout'] = number_format(round($aData['valid'] * $pps_value, 8), 8); $aData['payout'] = round($aData['valid'] * $pps_value, 8);
// Defaults // Defaults
$aData['fee' ] = 0; $aData['fee' ] = 0;
@ -73,18 +73,18 @@ foreach ($aAccountShares as $aData) {
// Calculate block fees // Calculate block fees
if ($config['fees'] > 0 && $aData['no_fees'] == 0) if ($config['fees'] > 0 && $aData['no_fees'] == 0)
$aData['fee'] = number_format(round($config['fees'] / 100 * $aData['payout'], 8), 8); $aData['fee'] = round($config['fees'] / 100 * $aData['payout'], 8);
// Calculate donation amount // Calculate donation amount
$aData['donation'] = number_format(round($user->getDonatePercent($user->getUserId($aData['username'])) / 100 * ( $aData['payout'] - $aData['fee']), 8), 8); $aData['donation'] = round($user->getDonatePercent($user->getUserId($aData['username'])) / 100 * ( $aData['payout'] - $aData['fee']), 8);
$log->logInfo($aData['id'] . "\t" . $log->logInfo($aData['id'] . "\t" .
$aData['username'] . "\t" . $aData['username'] . "\t" .
$aData['invalid'] . "\t" . $aData['invalid'] . "\t" .
$aData['valid'] . "\t*\t" . $aData['valid'] . "\t*\t" .
$pps_value . "\t=\t" . number_format($pps_value, 12) . "\t=\t" .
$aData['payout'] . "\t" . number_format($aData['payout'], 8) . "\t" .
$aData['donation'] . "\t" . number_format($aData['donation'], 8) . "\t" .
$aData['fee']); number_format($aData['fee']), 8);
// Add new credit transaction // Add new credit transaction
if (!$transaction->addTransaction($aData['id'], $aData['payout'], 'Credit_PPS')) if (!$transaction->addTransaction($aData['id'], $aData['payout'], 'Credit_PPS'))

View File

@ -60,26 +60,26 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
// Loop through all accounts that have found shares for this round // Loop through all accounts that have found shares for this round
foreach ($aAccountShares as $key => $aData) { foreach ($aAccountShares as $key => $aData) {
// Payout based on shares, PPS system // Payout based on shares, PPS system
$aData['percentage'] = number_format(round(( 100 / $iRoundShares ) * $aData['valid'], 8), 8); $aData['percentage'] = round(( 100 / $iRoundShares ) * $aData['valid'], 8);
$aData['payout'] = number_format(round(( $aData['percentage'] / 100 ) * $dReward, 8), 8); $aData['payout'] = round(( $aData['percentage'] / 100 ) * $dReward, 8);
// Defaults // Defaults
$aData['fee' ] = 0; $aData['fee' ] = 0;
$aData['donation'] = 0; $aData['donation'] = 0;
if ($config['fees'] > 0 && $aData['no_fees'] == 0) if ($config['fees'] > 0 && $aData['no_fees'] == 0)
$aData['fee'] = number_format(round($config['fees'] / 100 * $aData['payout'], 8), 8); $aData['fee'] = round($config['fees'] / 100 * $aData['payout'], 8);
// Calculate donation amount, fees not included // Calculate donation amount, fees not included
$aData['donation'] = number_format(round($user->getDonatePercent($user->getUserId($aData['username'])) / 100 * ( $aData['payout'] - $aData['fee']), 8), 8); $aData['donation'] = round($user->getDonatePercent($user->getUserId($aData['username'])) / 100 * ( $aData['payout'] - $aData['fee']), 8);
// Verbose output of this users calculations // Verbose output of this users calculations
$log->logInfo($aData['id'] . "\t" . $log->logInfo($aData['id'] . "\t" .
$aData['username'] . "\t" . $aData['username'] . "\t" .
$aData['valid'] . "\t" . $aData['valid'] . "\t" .
$aData['invalid'] . "\t" . $aData['invalid'] . "\t" .
$aData['percentage'] . "\t" . number_format($aData['percentage'], 8) . "\t" .
$aData['payout'] . "\t" . number_format($aData['payout'], 8) . "\t" .
$aData['donation'] . "\t" . number_format($aData['donation'], 8) . "\t" .
$aData['fee']); number_format($aData['fee']), 8);
// Update user share statistics // Update user share statistics
if (!$statistics->updateShareStatistics($aData, $aBlock['id'])) if (!$statistics->updateShareStatistics($aData, $aBlock['id']))

View File

@ -103,6 +103,9 @@ class Base {
} }
public function getParam() { public function getParam() {
$array = array_merge(array($this->types), $this->values); $array = array_merge(array($this->types), $this->values);
// Clear the data
$this->values = NULL;
$this->types = NULL;
// See here why we need this: http://stackoverflow.com/questions/16120822/mysqli-bind-param-expected-to-be-a-reference-value-given // See here why we need this: http://stackoverflow.com/questions/16120822/mysqli-bind-param-expected-to-be-a-reference-value-given
if (strnatcmp(phpversion(),'5.3') >= 0) { if (strnatcmp(phpversion(),'5.3') >= 0) {
$refs = array(); $refs = array();

View File

@ -402,10 +402,11 @@ class Statistics {
AND a.id = ? AND a.id = ?
GROUP BY HOUR(time)"); GROUP BY HOUR(time)");
if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $account_id, $account_id) && $stmt->execute() && $result = $stmt->get_result()) { if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $account_id, $account_id) && $stmt->execute() && $result = $stmt->get_result()) {
$aData = array(); $iStartHour = date('G');
while ($row = $result->fetch_assoc()) { for ($i = $iStartHour; $i < 24; $i++) $aData[$i] = 0;
$aData[$row['hour']] = $row['hashrate']; while ($row = $result->fetch_assoc()) $aData[$row['hour']] = $row['hashrate'];
} // Fill any non-existing hours with 0 hashrate
for ($i = 0; $i < 24; $i++) if (!array_key_exists($i, $aData)) $aData[$i] = 0;
return $this->memcache->setCache(__FUNCTION__ . $account_id, $aData); return $this->memcache->setCache(__FUNCTION__ . $account_id, $aData);
} }
// Catchall // Catchall
@ -438,10 +439,12 @@ class Statistics {
AND time > NOW() - INTERVAL 25 HOUR AND time > NOW() - INTERVAL 25 HOUR
GROUP BY HOUR(time)"); GROUP BY HOUR(time)");
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result()) { if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result()) {
while ($row = $result->fetch_assoc()) { $iStartHour = date('G');
$aData[$row['hour']] = $row['hashrate']; for ($i = $iStartHour; $i < 24; $i++) $aData[$i] = 0;
} while ($row = $result->fetch_assoc()) $aData[$row['hour']] = (int) $row['hashrate'];
return $this->memcache->setCache(__FUNCTION__, @$aData); // Fill any non-existing hours with 0 hashrate
for ($i = 0; $i < 24; $i++) if (!array_key_exists($i, $aData)) $aData[$i] = 0;
return $this->memcache->setCache(__FUNCTION__, $aData);
} }
// Catchall // Catchall
$this->debug->append("Failed to fetch hourly hashrate: " . $this->mysqli->error); $this->debug->append("Failed to fetch hourly hashrate: " . $this->mysqli->error);

View File

@ -47,6 +47,38 @@ class Transaction extends Base {
return false; return false;
} }
/**
* Fetch a transaction summary by type with total amounts
* @param account_id int Account ID, NULL for all
* @return data array type and total
**/
public function getTransactionSummary($account_id=NULL) {
$sql = "SELECT SUM(t.amount) AS total, t.type AS type FROM $this->table AS t";
if (!empty($account_id)) {
$sql .= " WHERE t.account_id = ? ";
$this->addParam('i', $account_id);
}
$sql .= " GROUP BY t.type";
$stmt = $this->mysqli->prepare($sql);
if (!empty($account_id)) {
if (!($this->checkStmt($stmt) && call_user_func_array( array($stmt, 'bind_param'), $this->getParam()) && $stmt->execute()))
return false;
$result = $stmt->get_result();
} else {
if (!($this->checkStmt($stmt) && $stmt->execute()))
return false;
$result = $stmt->get_result();
}
if ($result) {
$aData = NULL;
while ($row = $result->fetch_assoc()) {
$aData[$row['type']] = $row['total'];
}
return $aData;
}
return false;
}
/** /**
* Get all transactions from start for account_id * Get all transactions from start for account_id
* @param start int Starting point, id of transaction * @param start int Starting point, id of transaction
@ -72,52 +104,50 @@ class Transaction extends Base {
FROM $this->table AS t FROM $this->table AS t
LEFT JOIN " . $this->block->getTableName() . " AS b ON t.block_id = b.id LEFT JOIN " . $this->block->getTableName() . " AS b ON t.block_id = b.id
LEFT JOIN " . $this->user->getTableName() . " AS a ON t.account_id = a.id"; LEFT JOIN " . $this->user->getTableName() . " AS a ON t.account_id = a.id";
if (!empty($account_id)) {
$sql .= " WHERE ( t.account_id = ? ) ";
$this->addParam('i', $account_id);
}
if (is_array($filter)) { if (is_array($filter)) {
$aFilter = array(); $aFilter = array();
foreach ($filter as $key => $value) { foreach ($filter as $key => $value) {
if (!empty($value)) { if (!empty($value)) {
switch ($key) { switch ($key) {
case 'type': case 'type':
$aFilter[] = "t.type = ?"; $aFilter[] = "( t.type = ? )";
$this->addParam('s', $value); $this->addParam('s', $value);
break; break;
case 'status': case 'status':
switch ($value) { switch ($value) {
case 'Confirmed': case 'Confirmed':
if (empty($filter['type']) || ($filter['type'] != 'Debit_AP' && $filter['type'] != 'Debit_MP' && $filter['type'] != 'TXFee' && $filter['type'] != 'Credit_PPS' && $filter['type'] != 'Fee_PPS' && $filter['type'] != 'Donation_PPS')) { if (empty($filter['type']) || ($filter['type'] != 'Debit_AP' && $filter['type'] != 'Debit_MP' && $filter['type'] != 'TXFee' && $filter['type'] != 'Credit_PPS' && $filter['type'] != 'Fee_PPS' && $filter['type'] != 'Donation_PPS')) {
$aFilter[] = "b.confirmations >= " . $this->config['confirmations'] . " OR ISNULL(b.confirmations)"; $aFilter[] = "( b.confirmations >= " . $this->config['confirmations'] . " OR ISNULL(b.confirmations) )";
} }
break; break;
case 'Unconfirmed': case 'Unconfirmed':
$aFilter[] = "b.confirmations < " . $this->config['confirmations'] . " AND b.confirmations >= 0"; $aFilter[] = "( b.confirmations < " . $this->config['confirmations'] . " AND b.confirmations >= 0 )";
break; break;
case 'Orphan': case 'Orphan':
$aFilter[] = "b.confirmations = -1"; $aFilter[] = "( b.confirmations = -1 )";
break; break;
} }
break; break;
case 'account': case 'account':
$aFilter[] = "LOWER(a.username) = LOWER(?)"; $aFilter[] = "( LOWER(a.username) = LOWER(?) )";
$this->addParam('s', $value); $this->addParam('s', $value);
break; break;
case 'address': case 'address':
$aFilter[] = "t.coin_address = ?"; $aFilter[] = "( t.coin_address = ? )";
$this->addParam('s', $value); $this->addParam('s', $value);
break; break;
} }
} }
} }
if (!empty($aFilter)) { if (!empty($aFilter)) {
$sql .= " WHERE " . implode(' AND ', $aFilter); empty($account_id) ? $sql .= " WHERE " : $sql .= " AND ";
$sql .= implode(' AND ', $aFilter);
} }
} }
if (is_int($account_id) && empty($aFilter)) {
$sql .= " WHERE a.id = ?";
$this->addParam('i', $account_id);
} else if (is_int($account_id)) {
$sql .= " AND a.id = ?";
$this->addParam('i', $account_id);
}
$sql .= " $sql .= "
ORDER BY id DESC ORDER BY id DESC
LIMIT ?,? LIMIT ?,?

View File

@ -75,14 +75,15 @@ class Worker {
$this->debug->append("STA " . __METHOD__, 4); $this->debug->append("STA " . __METHOD__, 4);
$stmt = $this->mysqli->prepare(" $stmt = $this->mysqli->prepare("
SELECT account_id, id, username SELECT account_id, id, username
FROM " . $this->table . " FROM " . $this->table . " AS w
WHERE monitor = 1 AND ( SELECT SIGN(COUNT(id)) FROM " . $this->share->getTableName() . " WHERE username = $this->table.username AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)) = 0"); WHERE monitor = 1
AND (
SELECT IFNULL(SIGN(IF(our_result = 'Y', COUNT(id), 0)), 0) FROM " . $this->share->getTableName() . " WHERE username = w.username AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)
) = 0");
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_all(MYSQLI_ASSOC); return $result->fetch_all(MYSQLI_ASSOC);
// Catchall // Catchall
$this->setErrorMessage("Unable to fetch IDLE, monitored workers"); $this->setErrorMessage("Unable to fetch IDLE, monitored workers");
echo $this->mysqli->error;
return false; return false;
} }
@ -95,15 +96,27 @@ class Worker {
$this->debug->append("STA " . __METHOD__, 4); $this->debug->append("STA " . __METHOD__, 4);
$stmt = $this->mysqli->prepare(" $stmt = $this->mysqli->prepare("
SELECT id, username, password, monitor, SELECT id, username, password, monitor,
( SELECT SIGN(COUNT(id)) FROM " . $this->share->getTableName() . " WHERE username = $this->table.username AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)) AS active, (
( SELECT ROUND(COUNT(id) * POW(2, " . $this->config['difficulty'] . ")/600/1000) FROM " . $this->share->getTableName() . " WHERE username = $this->table.username AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)) AS hashrate SELECT
FROM $this->table IFNULL(IF(our_result='Y', ROUND(COUNT(id) * POW(2, " . $this->config['difficulty'] . ") / 600 / 1000), 0), 0) AS hashrate
FROM " . $this->share->getTableName() . "
WHERE
username = w.username
AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)
) + (
SELECT
IFNULL(IF(our_result='Y', ROUND(COUNT(id) * POW(2, " . $this->config['difficulty'] . ") / 600 / 1000), 0), 0) AS hashrate
FROM " . $this->share->getArchiveTableName() . "
WHERE
username = w.username
AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)
) AS hashrate
FROM $this->table AS w
WHERE id = ? WHERE id = ?
"); ");
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $id) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('i', $id) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_assoc(); return $result->fetch_assoc();
// Catchall // Catchall
echo $this->mysqli->error;
return false; return false;
} }
@ -116,9 +129,22 @@ class Worker {
$this->debug->append("STA " . __METHOD__, 4); $this->debug->append("STA " . __METHOD__, 4);
$stmt = $this->mysqli->prepare(" $stmt = $this->mysqli->prepare("
SELECT id, username, password, monitor, SELECT id, username, password, monitor,
( SELECT SIGN(COUNT(id)) FROM " . $this->share->getTableName() . " WHERE our_result = 'Y' AND username = $this->table.username AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)) AS active, (
( SELECT ROUND(COUNT(id) * POW(2, " . $this->config['difficulty'] . ")/600/1000) FROM " . $this->share->getTableName() . " WHERE our_result = 'Y' AND username = $this->table.username AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)) AS hashrate SELECT
FROM $this->table IFNULL(IF(our_result='Y', ROUND(COUNT(id) * POW(2, " . $this->config['difficulty'] . ") / 600 / 1000), 0), 0) AS hashrate
FROM " . $this->share->getTableName() . "
WHERE
username = w.username
AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)
) + (
SELECT
IFNULL(IF(our_result='Y', ROUND(COUNT(id) * POW(2, " . $this->config['difficulty'] . ") / 600 / 1000), 0), 0) AS hashrate
FROM " . $this->share->getArchiveTableName() . "
WHERE
username = w.username
AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)
) AS hashrate
FROM $this->table AS w
WHERE account_id = ?"); WHERE account_id = ?");
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $account_id) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('i', $account_id) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_all(MYSQLI_ASSOC); return $result->fetch_all(MYSQLI_ASSOC);
@ -135,7 +161,7 @@ class Worker {
**/ **/
public function getCountAllActiveWorkers() { public function getCountAllActiveWorkers() {
$this->debug->append("STA " . __METHOD__, 4); $this->debug->append("STA " . __METHOD__, 4);
$stmt = $this->mysqli->prepare("SELECT IFNULL(COUNT(DISTINCT username), 0) AS total FROM " . $this->share->getTableName() . " WHERE time > DATE_SUB(now(), INTERVAL 10 MINUTE)"); $stmt = $this->mysqli->prepare("SELECT IFNULL(IF(our_result='Y', COUNT(DISTINCT username), 0), 0) AS total FROM " . $this->share->getTableName() . " WHERE time > DATE_SUB(now(), INTERVAL 10 MINUTE)");
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_object()->total; return $result->fetch_object()->total;
return false; return false;

View File

@ -109,6 +109,7 @@ $config['ap_threshold']['max'] = 250;
* mobile : Enable/Disable mobile theme support * mobile : Enable/Disable mobile theme support
* mobile_theme : Theme used for mobile browsers * mobile_theme : Theme used for mobile browsers
* api disabled : Disable the sites API functions * api disabled : Disable the sites API functions
* blocks count : # of blocks to display on block statistics page
* *
* Defaults: * Defaults:
* title = `The Pool - Mining Evolved` * title = `The Pool - Mining Evolved`
@ -119,6 +120,7 @@ $config['ap_threshold']['max'] = 250;
* mobile = true * mobile = true
* mobile_theme = `mobile` * mobile_theme = `mobile`
* api disbabled = false * api disbabled = false
* blocks count = 20
**/ **/
$config['website']['title'] = 'The Pool - Mining Evolved'; $config['website']['title'] = 'The Pool - Mining Evolved';
$config['website']['name'] = 'The Pool'; $config['website']['name'] = 'The Pool';
@ -128,6 +130,7 @@ $config['website']['theme'] = 'mmcFE';
$config['website']['mobile'] = true; $config['website']['mobile'] = true;
$config['website']['mobile_theme'] = 'mobile'; $config['website']['mobile_theme'] = 'mobile';
$config['website']['api']['disabled'] = false; $config['website']['api']['disabled'] = false;
$config['website']['blocks']['count'] = 20;
/** /**
* Account specific settings * Account specific settings

View File

@ -6,11 +6,13 @@ if ($user->isAuthenticated()) {
$iLimit = 30; $iLimit = 30;
empty($_REQUEST['start']) ? $start = 0 : $start = $_REQUEST['start']; empty($_REQUEST['start']) ? $start = 0 : $start = $_REQUEST['start'];
$aTransactions = $transaction->getTransactions($start, @$_REQUEST['filter'], $iLimit, $_SESSION['USERDATA']['id']); $aTransactions = $transaction->getTransactions($start, @$_REQUEST['filter'], $iLimit, $_SESSION['USERDATA']['id']);
$aTransactionSummary = $transaction->getTransactionSummary($_SESSION['USERDATA']['id']);
$iCountTransactions = $transaction->num_rows; $iCountTransactions = $transaction->num_rows;
$aTransactionTypes = $transaction->getTypes(); $aTransactionTypes = $transaction->getTypes();
if (!$aTransactions) $_SESSION['POPUP'][] = array('CONTENT' => 'Could not find any transaction', 'TYPE' => 'errormsg'); if (!$aTransactions) $_SESSION['POPUP'][] = array('CONTENT' => 'Could not find any transaction', 'TYPE' => 'errormsg');
$smarty->assign('LIMIT', $iLimit); $smarty->assign('LIMIT', $iLimit);
$smarty->assign('TRANSACTIONS', $aTransactions); $smarty->assign('TRANSACTIONS', $aTransactions);
$smarty->assign('SUMMARY', $aTransactionSummary);
$smarty->assign('TRANSACTIONTYPES', $aTransactionTypes); $smarty->assign('TRANSACTIONTYPES', $aTransactionTypes);
$smarty->assign('TXSTATUS', array('' => '', 'Confirmed' => 'Confirmed', 'Unconfirmed' => 'Unconfirmed', 'Orphan' => 'Orphan')); $smarty->assign('TXSTATUS', array('' => '', 'Confirmed' => 'Confirmed', 'Unconfirmed' => 'Unconfirmed', 'Orphan' => 'Orphan'));
$smarty->assign('COUNTTRANSACTIONS', $iCountTransactions); $smarty->assign('COUNTTRANSACTIONS', $iCountTransactions);

View File

@ -14,11 +14,13 @@ 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);
empty($_REQUEST['start']) ? $start = 0 : $start = $_REQUEST['start']; empty($_REQUEST['start']) ? $start = 0 : $start = $_REQUEST['start'];
$aTransactions = $transaction->getTransactions($start, @$_REQUEST['filter'], $iLimit); $aTransactions = $transaction->getTransactions($start, @$_REQUEST['filter'], $iLimit);
$aTransactionSummary = $transaction->getTransactionSummary();
$iCountTransactions = $transaction->num_rows; $iCountTransactions = $transaction->num_rows;
$aTransactionTypes = $transaction->getTypes(); $aTransactionTypes = $transaction->getTypes();
if (!$aTransactions) $_SESSION['POPUP'][] = array('CONTENT' => 'Could not find any transaction', 'TYPE' => 'errormsg'); if (!$aTransactions) $_SESSION['POPUP'][] = array('CONTENT' => 'Could not find any transaction', 'TYPE' => 'errormsg');
$smarty->assign('LIMIT', $iLimit); $smarty->assign('LIMIT', $iLimit);
$smarty->assign('TRANSACTIONS', $aTransactions); $smarty->assign('TRANSACTIONS', $aTransactions);
$smarty->assign('SUMMARY', $aTransactionSummary);
$smarty->assign('TRANSACTIONTYPES', $aTransactionTypes); $smarty->assign('TRANSACTIONTYPES', $aTransactionTypes);
$smarty->assign('TXSTATUS', array('' => '', 'Confirmed' => 'Confirmed', 'Unconfirmed' => 'Unconfirmed', 'Orphan' => 'Orphan')); $smarty->assign('TXSTATUS', array('' => '', 'Confirmed' => 'Confirmed', 'Unconfirmed' => 'Unconfirmed', 'Orphan' => 'Orphan'));
$smarty->assign('COUNTTRANSACTIONS', $iCountTransactions); $smarty->assign('COUNTTRANSACTIONS', $iCountTransactions);

View File

@ -7,7 +7,7 @@ if (!defined('SECURITY')) die('Hacking attempt');
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);
// Grab the last blocks found // Grab the last blocks found
$iLimit = 20; !empty($config['website']['blocks']['count']) ? $iLimit = $config['website']['blocks']['count'] : $iLimit = 20;
$aBlocksFoundData = $statistics->getBlocksFound($iLimit); $aBlocksFoundData = $statistics->getBlocksFound($iLimit);
// Propagate content our template // Propagate content our template

View File

@ -12,14 +12,13 @@ $dDifficulty = 1;
$aRoundShares = 1; $aRoundShares = 1;
// Only run these if the user is logged in // Only run these if the user is logged in
if (@$_SESSION['AUTHENTICATED']) { $aRoundShares = $statistics->getRoundShares();
$aRoundShares = $statistics->getRoundShares(); if ($bitcoin->can_connect() === true) {
if ($bitcoin->can_connect() === true) { $dDifficulty = $bitcoin->query('getdifficulty');
$dDifficulty = $bitcoin->query('getdifficulty'); if (is_array($dDifficulty) && array_key_exists('proof-of-work', $dDifficulty))
if (is_array($dDifficulty) && array_key_exists('proof-of-work', $dDifficulty)) $dDifficulty = $dDifficulty['proof-of-work'];
$dDifficulty = $dDifficulty['proof-of-work'];
}
} }
// Always fetch this since we need for ministats header // Always fetch this since we need for ministats header
$bitcoin->can_connect() === true ? $dNetworkHashrate = $bitcoin->query('getnetworkhashps') : $dNetworkHashrate = 0; $bitcoin->can_connect() === true ? $dNetworkHashrate = $bitcoin->query('getnetworkhashps') : $dNetworkHashrate = 0;

View File

@ -1,3 +1,22 @@
{include file="global/block_header.tpl" BLOCK_HEADER="Transaction Summary"}
<table>
<thead>
<tr>
{foreach $SUMMARY as $type=>$total}
<th>{$type}</th>
{/foreach}
</tr>
</thead>
<tbody>
<tr>
{foreach $SUMMARY as $type=>$total}
<td class="right">{$total}</td>
{/foreach}
</tr>
</tbody>
</table>
{include file="global/block_footer.tpl"}
{include file="global/block_header.tpl" ALIGN="left" BLOCK_STYLE="width: 23%" BLOCK_HEADER="Transaction Filter"} {include file="global/block_header.tpl" ALIGN="left" BLOCK_STYLE="width: 23%" BLOCK_HEADER="Transaction Filter"}
<form action="{$smarty.server.PHP_SELF}"> <form action="{$smarty.server.PHP_SELF}">
<input type="hidden" name="page" value="{$smarty.request.page}" /> <input type="hidden" name="page" value="{$smarty.request.page}" />
@ -25,11 +44,11 @@
</td> </td>
</tr> </tr>
<tr> <tr>
<td class="left">TX Type</td> <td class="left">Type</td>
<td class="right">{html_options name="filter[type]" options=$TRANSACTIONTYPES selected=$smarty.request.filter.type|default:""}</td> <td class="right">{html_options name="filter[type]" options=$TRANSACTIONTYPES selected=$smarty.request.filter.type|default:""}</td>
</tr> </tr>
<tr> <tr>
<td class="left">TX Status</td> <td class="left">Status</td>
<td class="right">{html_options name="filter[status]" options=$TXSTATUS selected=$smarty.request.filter.status|default:""}</td> <td class="right">{html_options name="filter[status]" options=$TXSTATUS selected=$smarty.request.filter.status|default:""}</td>
</tr> </tr>
<tr> <tr>

View File

@ -19,9 +19,9 @@
{section worker $WORKERS} {section worker $WORKERS}
{assign var="username" value="."|escape|explode:$WORKERS[worker].username:2} {assign var="username" value="."|escape|explode:$WORKERS[worker].username:2}
<tr> <tr>
<td{if $WORKERS[worker].active} style="color: orange"{/if}>{$username.0|escape}.<input name="data[{$WORKERS[worker].id}][username]" value="{$username.1|escape}" size="10" required/></td> <td{if $WORKERS[worker].hashrate > 0} style="color: orange"{/if}>{$username.0|escape}.<input name="data[{$WORKERS[worker].id}][username]" value="{$username.1|escape}" size="10" required/></td>
<td><input type="text" name="data[{$WORKERS[worker].id}][password]" value="{$WORKERS[worker].password|escape}" size="10" required></td> <td><input type="text" name="data[{$WORKERS[worker].id}][password]" value="{$WORKERS[worker].password|escape}" size="10" required></td>
<td class="center"><img src="{$PATH}/images/{if $WORKERS[worker].active}success{else}error{/if}.gif" /></td> <td class="center"><img src="{$PATH}/images/{if $WORKERS[worker].hashrate > 0}success{else}error{/if}.gif" /></td>
{if $GLOBAL.config.disable_notifications != 1} {if $GLOBAL.config.disable_notifications != 1}
<td class="center"> <td class="center">
<input type="checkbox" name="data[{$WORKERS[worker].id}][monitor]" value="1" id="data[{$WORKERS[worker].id}][monitor]" {if $WORKERS[worker].monitor}checked{/if} /> <input type="checkbox" name="data[{$WORKERS[worker].id}][monitor]" value="1" id="data[{$WORKERS[worker].id}][monitor]" {if $WORKERS[worker].monitor}checked{/if} />

View File

@ -1,3 +1,22 @@
{include file="global/block_header.tpl" BLOCK_HEADER="Transaction Summary"}
<table>
<thead>
<tr>
{foreach $SUMMARY as $type=>$total}
<th>{$type}</th>
{/foreach}
</tr>
</thead>
<tbody>
<tr>
{foreach $SUMMARY as $type=>$total}
<td class="right">{$total}</td>
{/foreach}
</tr>
</tbody>
</table>
{include file="global/block_footer.tpl"}
{include file="global/block_header.tpl" ALIGN="left" BLOCK_STYLE="width: 23%" BLOCK_HEADER="Transaction Filter"} {include file="global/block_header.tpl" ALIGN="left" BLOCK_STYLE="width: 23%" BLOCK_HEADER="Transaction Filter"}
<form action="{$smarty.server.PHP_SELF}"> <form action="{$smarty.server.PHP_SELF}">
<input type="hidden" name="page" value="{$smarty.request.page}" /> <input type="hidden" name="page" value="{$smarty.request.page}" />
@ -25,11 +44,11 @@
</td> </td>
</tr> </tr>
<tr> <tr>
<td class="left">TX Type</td> <td class="left">Type</td>
<td class="right">{html_options name="filter[type]" options=$TRANSACTIONTYPES selected=$smarty.request.filter.type|default:""}</td> <td class="right">{html_options name="filter[type]" options=$TRANSACTIONTYPES selected=$smarty.request.filter.type|default:""}</td>
</tr> </tr>
<tr> <tr>
<td class="left">TX Status</td> <td class="left">Status</td>
<td class="right">{html_options name="filter[status]" options=$TXSTATUS selected=$smarty.request.filter.status|default:""}</td> <td class="right">{html_options name="filter[status]" options=$TXSTATUS selected=$smarty.request.filter.status|default:""}</td>
</tr> </tr>
<tr> <tr>

View File

@ -28,6 +28,10 @@
<td><b>Pool Valid</b></td> <td><b>Pool Valid</b></td>
<td class="right"><i>{$GLOBAL.roundshares.valid|number_format}</i></td> <td class="right"><i>{$GLOBAL.roundshares.valid|number_format}</i></td>
</tr> </tr>
<tr>
<td><b>Your Valid</b></td>
<td class="right"><i>{$GLOBAL.userdata.shares.valid|number_format}</i></td>
</tr>
<tr> <tr>
<td><b>Pool Invalid</b></td> <td><b>Pool Invalid</b></td>
<td class="right"><i>{$GLOBAL.roundshares.invalid|number_format}</i>{if $GLOBAL.roundshares.valid > 0}<font size='1px'> ({($GLOBAL.roundshares.invalid / ($GLOBAL.roundshares.valid + $GLOBAL.roundshares.invalid) * 100)|number_format:"2"}%)</font>{/if}</td> <td class="right"><i>{$GLOBAL.roundshares.invalid|number_format}</i>{if $GLOBAL.roundshares.valid > 0}<font size='1px'> ({($GLOBAL.roundshares.invalid / ($GLOBAL.roundshares.valid + $GLOBAL.roundshares.invalid) * 100)|number_format:"2"}%)</font>{/if}</td>

View File

@ -32,7 +32,7 @@ target and network difficulty and assuming a zero variance scenario.
{include file="global/block_header.tpl" BLOCK_HEADER="Last $BLOCKLIMIT Blocks Found" BLOCK_STYLE="clear:none;"} {include file="global/block_header.tpl" BLOCK_HEADER="Last $BLOCKLIMIT Blocks Found" BLOCK_STYLE="clear:none;"}
<center> <center>
<table width="100%" style="font-size:13px;"> <table width="100%" class="sortable" style="font-size:13px;">
<thead> <thead>
<tr style="background-color:#B6DAFF;"> <tr style="background-color:#B6DAFF;">
<th class="center">Block</th> <th class="center">Block</th>
@ -47,10 +47,15 @@ target and network difficulty and assuming a zero variance scenario.
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{assign var=rank value=1} {assign var=count value=0}
{assign var=totalexpectedshares value=0}
{assign var=totalshares value=0}
{assign var=totalpercentage value=0}
{section block $BLOCKSFOUND} {section block $BLOCKSFOUND}
{assign var="totalshares" value=$totalshares+$BLOCKSFOUND[block].shares}
{assign var="count" value=$count+1}
<tr class="{cycle values="odd,even"}"> <tr class="{cycle values="odd,even"}">
<td class="center"><a href="{$GLOBAL.blockexplorer}{$BLOCKSFOUND[block].height}" target="_blank">{$BLOCKSFOUND[block].height}</a></td> <td class="center"><a href="{$GLOBAL.blockexplorer}{$BLOCKSFOUND[block].blockhash}" target="_blank">{$BLOCKSFOUND[block].height}</a></td>
<td class="center"> <td class="center">
{if $BLOCKSFOUND[block].confirmations >= $GLOBAL.confirmations} {if $BLOCKSFOUND[block].confirmations >= $GLOBAL.confirmations}
<font color="green">Confirmed</font> <font color="green">Confirmed</font>
@ -63,15 +68,23 @@ target and network difficulty and assuming a zero variance scenario.
<td class="right">{$BLOCKSFOUND[block].amount|number_format:"2"}</td> <td class="right">{$BLOCKSFOUND[block].amount|number_format:"2"}</td>
<td class="right"> <td class="right">
{math assign="estshares" equation="(pow(2,32 - targetdiff) * blockdiff)" targetdiff=$GLOBAL.config.targetdiff blockdiff=$BLOCKSFOUND[block].difficulty} {math assign="estshares" equation="(pow(2,32 - targetdiff) * blockdiff)" targetdiff=$GLOBAL.config.targetdiff blockdiff=$BLOCKSFOUND[block].difficulty}
{assign var="totalexpectedshares" value=$totalexpectedshares+$estshares}
{$estshares|number_format} {$estshares|number_format}
</td> </td>
<td class="right">{$BLOCKSFOUND[block].shares|number_format}</td> <td class="right">{$BLOCKSFOUND[block].shares|number_format}</td>
<td class="right"> <td class="right">
{math assign="percentage" equation="shares / estshares * 100" shares=$BLOCKSFOUND[block].shares estshares=$estshares} {math assign="percentage" equation="shares / estshares * 100" shares=$BLOCKSFOUND[block].shares estshares=$estshares}
{assign var="totalpercentage" value=$totalpercentage+$percentage}
<font color="{if ($percentage <= 100)}green{else}red{/if}">{$percentage|number_format:"2"}</font> <font color="{if ($percentage <= 100)}green{else}red{/if}">{$percentage|number_format:"2"}</font>
</td> </td>
</tr> </tr>
{/section} {/section}
<tr>
<td colspan="6" class="right"><b>Totals</b></td>
<td class="right">{$totalexpectedshares|number_format}</td>
<td class="right">{$totalshares|number_format}</td>
<td class="right"><font color="{if (($totalpercentage / $count) <= 100)}green{else}red{/if}">{($totalpercentage / $count)|number_format:"2"}</font>
</tr>
</tbody> </tbody>
</table> </table>
</center> </center>

View File

@ -13,7 +13,7 @@
{assign var=rank value=1} {assign var=rank value=1}
{section block $BLOCKSFOUND} {section block $BLOCKSFOUND}
<tr class="{cycle values="odd,even"}"> <tr class="{cycle values="odd,even"}">
<td class="center"><a href="{$GLOBAL.blockexplorer}{$BLOCKSFOUND[block].height}" target="_blank">{$BLOCKSFOUND[block].height}</a></td> <td class="center"><a href="{$GLOBAL.blockexplorer}{$BLOCKSFOUND[block].blockhash}" target="_new">{$BLOCKSFOUND[block].height}</a></td>
<td>{if $BLOCKSFOUND[block].is_anonymous|default:"0" == 1}anonymous{else}{$BLOCKSFOUND[block].finder|default:"unknown"|escape}{/if}</td> <td>{if $BLOCKSFOUND[block].is_anonymous|default:"0" == 1}anonymous{else}{$BLOCKSFOUND[block].finder|default:"unknown"|escape}{/if}</td>
<td class="center">{$BLOCKSFOUND[block].time|date_format:"%d/%m %H:%M:%S"}</td> <td class="center">{$BLOCKSFOUND[block].time|date_format:"%d/%m %H:%M:%S"}</td>
<td class="right">{$BLOCKSFOUND[block].shares|number_format}</td> <td class="right">{$BLOCKSFOUND[block].shares|number_format}</td>

View File

@ -5,32 +5,23 @@
<thead> <thead>
<tr> <tr>
<td></td> <td></td>
{for $i=date('G') to 23} {foreach $YOURHASHRATES as $hour=>$hashrate}
<th scope="col">{$i}:00</th> <th scope="col">{$hour|default:"0"}:00</th>
{/for} {/foreach}
{for $i=0 to date('G', time () - 60 * 60)}
<th scope="col">{$i}:00</th>
{/for}
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<th scope="row">{$smarty.session.USERDATA.username}</th> <th scope="row">{$smarty.session.USERDATA.username}</th>
{for $i=date('G') to 23} {foreach $YOURHASHRATES as $hour=>$hashrate}
<td>{$YOURHASHRATES.$i|default:"0"}</td> <td>{$hashrate|default:"0"}</td>
{/for} {/foreach}
{for $i=0 to date('G', time() - 60 * 60)}
<td>{$YOURHASHRATES.$i|default:"0"}</td>
{/for}
</tr> </tr>
<tr> <tr>
<th scope="row">Pool</th> <th scope="row">Pool</th>
{for $i=date('G') to 23} {foreach $POOLHASHRATES as $hour=>$hashrate}
<td>{$POOLHASHRATES.$i|default:"0"}</td> <td>{$hashrate|default:"0"}</td>
{/for} {/foreach}
{for $i=0 to date('G', time() - 60 * 60)}
<td>{$POOLHASHRATES.$i - $YOURHASHRATES.$i|default:"0"}</td>
{/for}
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@ -5,23 +5,17 @@
<thead> <thead>
<tr> <tr>
<td></td> <td></td>
{for $i=date('G') to 23} {foreach $YOURHASHRATES as $hour=>$hashrate}
<th scope="col">{$i}:00</th> <th scope="col">{$hour|default:"0"}:00</th>
{/for} {/foreach}
{for $i=0 to date('G', time () - 60 * 60)}
<th scope="col">{$i}:00</th>
{/for}
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<th scope="row">{$smarty.session.USERDATA.username}</th> <th scope="row">{$smarty.session.USERDATA.username}</th>
{for $i=date('G') to 23} {foreach $YOURHASHRATES as $hour=>$hashrate}
<td>{$YOURHASHRATES.$i|default:"0"}</td> <td>{$hashrate|default:"0"}</td>
{/for} {/foreach}
{for $i=0 to date('G', time() - 60 * 60)}
<td>{$YOURHASHRATES.$i|default:"0"}</td>
{/for}
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@ -5,23 +5,17 @@
<thead> <thead>
<tr> <tr>
<td></td> <td></td>
{for $i=date('G') to 23} {foreach $POOLHASHRATES as $hour=>$hashrate}
<th scope="col">{$i}:00</th> <th scope="col">{$hour|default:"0"}:00</th>
{/for} {/foreach}
{for $i=0 to date('G', time () - 60 * 60)}
<th scope="col">{$i}:00</th>
{/for}
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<th scope="row">Pool</th> <th scope="row">Pool</th>
{for $i=date('G') to 23} {foreach $POOLHASHRATES as $hour=>$hashrate}
<td>{$POOLHASHRATES.$i|default:"0"}</td> <td>{$hashrate|default:"0"}</td>
{/for} {/foreach}
{for $i=0 to date('G', time() - 60 * 60)}
<td>{$POOLHASHRATES.$i|default:"0"}</td>
{/for}
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@ -9,7 +9,7 @@
{assign var="username" value="."|escape|explode:$WORKERS[worker].username:2} {assign var="username" value="."|escape|explode:$WORKERS[worker].username:2}
<tr> <tr>
<td align="left"{if $WORKERS[worker].active} style="color: orange"{/if}>{$username.0|escape}.{$username.1|escape}</td> <td align="left"{if $WORKERS[worker].active} style="color: orange"{/if}>{$username.0|escape}.{$username.1|escape}</td>
<td align="center"><img src="{$PATH}/images/{if $WORKERS[worker].active}success{else}error{/if}.gif" /></td> <td align="center"><img src="{$PATH}/images/{if $WORKERS[worker].hashrate > 0}success{else}error{/if}.gif" /></td>
<td align="right">{$WORKERS[worker].hashrate|number_format}</td> <td align="right">{$WORKERS[worker].hashrate|number_format}</td>
</tr> </tr>
{/section} {/section}

View File

@ -53,7 +53,7 @@ target and network difficulty and assuming a zero variance scenario.
{else if $BLOCKSFOUND[block].confirmations == -1} {else if $BLOCKSFOUND[block].confirmations == -1}
<font color="red">Orphan</font> <font color="red">Orphan</font>
{else}{$GLOBAL.confirmations - $BLOCKSFOUND[block].confirmations} left{/if}</td> {else}{$GLOBAL.confirmations - $BLOCKSFOUND[block].confirmations} left{/if}</td>
<td>{$BLOCKSFOUND[block].finder|default:"unknown"}</td> <td>{if $BLOCKSFOUND[block].is_anonymous|default:"0" == 1}anonymous{else}{$BLOCKSFOUND[block].finder|default:"unknown"|escape}{/if}</td>
<td class="center">{$BLOCKSFOUND[block].time|date_format:"%d/%m %H:%M:%S"}</td> <td class="center">{$BLOCKSFOUND[block].time|date_format:"%d/%m %H:%M:%S"}</td>
<td class="right">{$BLOCKSFOUND[block].difficulty|number_format:"2"}</td> <td class="right">{$BLOCKSFOUND[block].difficulty|number_format:"2"}</td>
<td class="right">{(pow(2,32 - $GLOBAL.config.targetdiff) * $BLOCKSFOUND[block].difficulty)|number_format}</td> <td class="right">{(pow(2,32 - $GLOBAL.config.targetdiff) * $BLOCKSFOUND[block].difficulty)|number_format}</td>

View File

@ -13,7 +13,7 @@
{section block $BLOCKSFOUND} {section block $BLOCKSFOUND}
<tr class="{cycle values="odd,even"}"> <tr class="{cycle values="odd,even"}">
<th><a href="{$GLOBAL.blockexplorer}{$BLOCKSFOUND[block].height}" target="_blank">{$BLOCKSFOUND[block].height}</a></th> <th><a href="{$GLOBAL.blockexplorer}{$BLOCKSFOUND[block].height}" target="_blank">{$BLOCKSFOUND[block].height}</a></th>
<td>{$BLOCKSFOUND[block].finder|default:"unknown"}</td> <td>{if $BLOCKSFOUND[block].is_anonymous|default:"0" == 1}anonymous{else}{$BLOCKSFOUND[block].finder|default:"unknown"|escape}{/if}</td>
<td>{$BLOCKSFOUND[block].time|date_format:"%d/%m %H:%M"}</td> <td>{$BLOCKSFOUND[block].time|date_format:"%d/%m %H:%M"}</td>
<td align="right">{$BLOCKSFOUND[block].shares|number_format}</td> <td align="right">{$BLOCKSFOUND[block].shares|number_format}</td>
</tr> </tr>

View File

@ -16,7 +16,7 @@
{if $GLOBAL.userdata.username == $CONTRIBSHARES[contrib].account}{assign var=listed value=1}{/if} {if $GLOBAL.userdata.username == $CONTRIBSHARES[contrib].account}{assign var=listed value=1}{/if}
<tr> <tr>
<th>{$rank++}</th> <th>{$rank++}</th>
<td>{$CONTRIBHASHES[contrib].account}</td> <td>{if $CONTRIBHASHES[contrib].is_anonymous|default:"0" == 1}anonymous{else}{$CONTRIBHASHES[contrib].account|escape}{/if}</td>
<td align="right">{$CONTRIBHASHES[contrib].hashrate|number_format}</td> <td align="right">{$CONTRIBHASHES[contrib].hashrate|number_format}</td>
<td align="right">{$estday|number_format:"3"}</td> <td align="right">{$estday|number_format:"3"}</td>
<td align="right">{($estday * $GLOBAL.price)|default:"n/a"|number_format:"2"}</td> <td align="right">{($estday * $GLOBAL.price)|default:"n/a"|number_format:"2"}</td>

View File

@ -9,12 +9,12 @@
<tbody> <tbody>
{assign var=rank value=1} {assign var=rank value=1}
{assign var=listed value=0} {assign var=listed value=0}
{section hashrate $CONTRIBSHARES} {section shares $CONTRIBSHARES}
{if $GLOBAL.userdata.username == $CONTRIBSHARES[hashrate].account}{assign var=listed value=1}{/if} {if $GLOBAL.userdata.username == $CONTRIBSHARES[shares].account}{assign var=listed value=1}{/if}
<tr> <tr>
<th aign="center">{$rank++}</th> <th aign="center">{$rank++}</th>
<td>{$CONTRIBSHARES[hashrate].account}</td> <td>{if $CONTRIBSHARES[shares].is_anonymous|default:"0" == 1}anonymous{else}{$CONTRIBSHARES[shares].account|escape}{/if}</td>
<td align="right">{$CONTRIBSHARES[hashrate].shares|number_format}</td> <td align="right">{$CONTRIBSHARES[shares].shares|number_format}</td>
</tr> </tr>
{/section} {/section}
{if $listed != 1} {if $listed != 1}