Merge pull request #6 from TheSerapher/next

Next
This commit is contained in:
obigal 2013-07-05 21:23:34 -07:00
commit 43cf51efbf
38 changed files with 373 additions and 149 deletions

70
POOLS.md Normal file
View File

@ -0,0 +1,70 @@
Pools running mmcfe-ng
======================
If you are not sure if you want to use `mmcfe-ng` on your own pool,
maybe this list will push you over the edge of decision making. Some
small and large pools are already running on it and have succesfully
tested it on various coins.
These tables represent their users pools. Be aware that all values are
as of this writing and may have changed since then.
### ahmedbodi
A helpful tester for features and bug fixes in `mmcfe-ng`, he is running
an active pool for Redcoin.
| Pool URL | Coin | Avg. Hashrate | Avg. Active Workers | Notes |
| :------- | :--- | ------------: | ------------------: | ----- |
| http://crypto-expert.com/REDpool/public | Redcoin | 10 MHash | 12 | No modifications required |
| http://crypto-expert.com/ANONpool/public | Anoncoin | 0 MHash | 0 | Template Changes |
### vias79
Vias is using mmcfe-ng with a small group of people to mine various coins.
They have succesfully mined blocks on each of those pools listed.
All pools are running on Stratum only.
| Pool URL | Coin | Avg. Hashrate | Avg. Active Workers | Notes |
| -------- | ---- | ------------- | ----------------- | ----- |
| http://wdc.nordicminers.eu | Worldcoin | n/a | n/a | |
| http://lky.nordicminers.eu | Luckycoin | n/a | n/a | |
| http://fst.nordicminers.eu | Fastcoin | n/a | n/a | |
| http://dgc.nordicminers.eu | Digitalcoin | n/a | n/a | |
| http://ezc.nordicminers.eu | Ezcoin | n/a | n/a | |
| http://sbc.nordicminers.eu | Stablecoin | n/a | n/a | |
| http://mnc.nordicminers.eu | Mincoin | n/a | n/a | |
| http://arg.nordicminers.eu | Argentum | n/a | n/a | |
| http://mem.nordicminers.eu | Memecoin | n/a | n/a | |
| http://frk.nordicminers.eu | Franko | n/a | n/a | |
| http://pxc.nordicminers.eu | Phenixcoin | n/a | n/a | |
### WKNiGHT
WKNiGHT was an early adopter of `mmcfe-ng`. He has been around since a first stable release
which only featured proportional payouts. He successfully moved to PPS since then and is
running more or less without any issues (related to `mmcfe-ng` that is ;-)). He is also running
the most powerful pool!
| Pool URL | Coin | Avg. Hashrate | Avg. Active Workers | Notes |
| -------- | ---- | ------------- | ----------------- | ----- |
| http://www.ejpool.info | Litecoin | 155 MHash | 120 | |
### Obigal
Small Time Miners are running various stratum only pools for different coins.
| Pool URL | Coin | Avg. Hashrate | Avg. Active Workers | Notes |
| -------- | ---- | ------------- | ------------------- | ----- |
| http://meg.smalltimeminer.com | Megacoin | 5 - 10 MHash | n/a | |
| http://flo.smalltimeminer.com | Florincoin | 5 - 6 MHash | n/a | |
| http://alf.smalltimeminer.com | Alphacoin | 2 - 4 MHash | n/a | |
| http://cgb.smalltimeminer.com | Cryptobullion | 2 - 4 MHash | n/a | PoS/PoW type coin
### Feeleep75
| Pool URL | Coin | Avg. Hashrate | Avg. Active Workers | Notes |
| -------- | ---- | ------------- | ------------------- | ----- |
| http://bot.coinmine.pl | Bottlecaps | 3 - 50 MHash | n/a | PoS/PoW type coin |
| http://yacp.coinmine.pl | YaCoin | 19 MHash | n/a | |

View File

@ -33,6 +33,11 @@ These people have supported this project with a donation:
* [WKNiGHT](https://github.com/WKNiGHT-)
* [ZC](https://github.com/zccopwrx)
Pools running mmcfe-ng
======================
You can find a list of active pools [here](POOLS.md).
Requirements
============

View File

@ -77,7 +77,7 @@ if (empty($aAllBlocks)) {
foreach ($aAllBlocks as $iIndex => $aBlock) {
if (empty($aBlock['share_id'])) {
// Fetch this blocks upstream ID
if ($share->setUpstream($block->getLastUpstreamId())) {
if ($share->setUpstream($block->getLastUpstreamId(), $aBlock['time'])) {
$iCurrentUpstreamId = $share->getUpstreamId();
$iAccountId = $user->getUserId($share->getUpstreamFinder());
} else {
@ -85,6 +85,7 @@ if (empty($aAllBlocks)) {
verbose($share->getError() . "\n");
exit;
}
// Fetch share information
if (!$iPreviousShareId = $block->getLastShareId()) {
$iPreviousShareId = 0;

View File

@ -40,7 +40,16 @@ if ( $bitcoin->can_connect() === true ){
}
// Value per share calculation
$pps_value = number_format(round(50 / (pow(2,32) * $dDifficulty) * pow(2, $config['difficulty']), 12) ,12);
if ($config['reward_type'] != 'block') {
$pps_value = number_format(round($config['reward'] / (pow(2,32) * $dDifficulty) * pow(2, $config['difficulty']), 12) ,12);
} else {
// Try to find the last block value and use that for future payouts, revert to fixed reward if none found
if ($aLastBlock = $block->getLast()) {
$pps_value = number_format(round($aLastBlock['amount'] / (pow(2,32) * $dDifficulty) * pow(2, $config['difficulty']), 12) ,12);
} else {
$pps_value = number_format(round($config['reward'] / (pow(2,32) * $dDifficulty) * pow(2, $config['difficulty']), 12) ,12);
}
}
// Find our last share accounted and last inserted share for PPS calculations
$iPreviousShareId = $setting->getValue('pps_last_share_id');

View File

@ -99,12 +99,16 @@ class Notification extends Mail {
$this->debug->append("STA " . __METHOD__, 4);
$stmt = $this->mysqli->prepare("SELECT * FROM $this->tableSettings WHERE account_id = ?");
if ($stmt && $stmt->bind_param('i', $account_id) && $stmt->execute() && $result = $stmt->get_result()) {
while ($row = $result->fetch_assoc()) {
$aData[$row['type']] = $row['active'];
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
$aData[$row['type']] = $row['active'];
}
return $aData;
}
return $aData;
}
// Catchall
$this->setErrorMessage('Unable to fetch notification settings');
$this->debug->append('Failed fetching notification settings for ' . $account_id . ': ' . $this->mysqli->error);
return false;
}

View File

@ -177,15 +177,16 @@ class Share {
* @param last int Skips all shares up to last to find new share
* @return bool
**/
public function setUpstream($last=0) {
public function setUpstream($last=0, $time=0) {
$stmt = $this->mysqli->prepare("
SELECT
SUBSTRING_INDEX( `username` , '.', 1 ) AS account, id
FROM $this->table
WHERE upstream_result = 'Y'
AND id > ?
AND UNIX_TIMESTAMP(time) >= ?
ORDER BY id ASC LIMIT 1");
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $last) && $stmt->execute() && $result = $stmt->get_result()) {
if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $last, $time) && $stmt->execute() && $result = $stmt->get_result()) {
$this->oUpstream = $result->fetch_object();
if (!empty($this->oUpstream->account) && is_int($this->oUpstream->id))
return true;

View File

@ -99,8 +99,19 @@ class Statistics {
$this->debug->append("STA " . __METHOD__, 4);
if ($this->getGetCache() && $data = $this->memcache->get(__FUNCTION__)) return $data;
$stmt = $this->mysqli->prepare("
SELECT ROUND(COUNT(id) * POW(2, " . $this->config['difficulty'] . ")/600/1000) AS hashrate FROM " . $this->share->getTableName() . " WHERE time > DATE_SUB(now(), INTERVAL 10 MINUTE)
");
SELECT
(
(
SELECT IFNULL(ROUND(COUNT(id) * POW(2, " . $this->config['difficulty'] . ")/600/1000), 0) AS hashrate
FROM " . $this->share->getTableName() . "
WHERE time > DATE_SUB(now(), INTERVAL 10 MINUTE)
) + (
SELECT IFNULL(ROUND(COUNT(id) * POW(2, " . $this->config['difficulty'] . ")/600/1000), 0) AS hashrate
FROM " . $this->share->getArchiveTableName() . "
WHERE time > DATE_SUB(now(), INTERVAL 10 MINUTE)
)
) AS hashrate
FROM DUAL");
// Catchall
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result() ) return $this->memcache->setCache(__FUNCTION__, $result->fetch_object()->hashrate);
$this->debug->append("Failed to get hashrate: " . $this->mysqli->error);
@ -116,8 +127,9 @@ class Statistics {
$this->debug->append("STA " . __METHOD__, 4);
if ($data = $this->memcache->get(__FUNCTION__)) return $data;
$stmt = $this->mysqli->prepare("
SELECT ROUND(COUNT(id) / 600, 2) AS sharerate FROM " . $this->share->getTableName() . " WHERE time > DATE_SUB(now(), INTERVAL 10 MINUTE)
");
SELECT ROUND(COUNT(id) / 600, 2) AS sharerate
FROM " . $this->share->getTableName() . "
WHERE time > DATE_SUB(now(), INTERVAL 10 MINUTE)");
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result() ) return $this->memcache->setCache(__FUNCTION__, $result->fetch_object()->sharerate);
// Catchall
$this->debug->append("Failed to fetch share rate: " . $this->mysqli->error);
@ -134,8 +146,8 @@ class Statistics {
if ($this->getGetCache() && $data = $this->memcache->get(__FUNCTION__)) return $data;
$stmt = $this->mysqli->prepare("
SELECT
SUM(IF(our_result='Y', 1, 0)) AS valid,
SUM(IF(our_result='N', 1, 0)) AS invalid
IFNULL(SUM(IF(our_result='Y', 1, 0)), 0) AS valid,
IFNULL(SUM(IF(our_result='N', 1, 0)), 0) AS invalid
FROM " . $this->share->getTableName() . "
WHERE UNIX_TIMESTAMP(time) >IFNULL((SELECT MAX(time) FROM " . $this->block->getTableName() . "),0)");
if ( $this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result() )
@ -156,14 +168,13 @@ class Statistics {
if ($this->getGetCache() && $data = $this->memcache->get(__FUNCTION__)) return $data;
$stmt = $this->mysqli->prepare("
SELECT
SUM(IF(our_result='Y', 1, 0)) AS valid,
SUM(IF(our_result='N', 1, 0)) AS invalid,
u.id AS id,
u.username AS username
IFNULL(SUM(IF(our_result='Y', 1, 0)), 0) AS valid,
IFNULL(SUM(IF(our_result='N', 1, 0)), 0) AS invalid,
u.id AS id,
u.username AS username
FROM " . $this->share->getTableName() . " AS s,
" . $this->user->getTableName() . " AS u
WHERE
u.username = SUBSTRING_INDEX( s.username, '.', 1 )
" . $this->user->getTableName() . " AS u
WHERE u.username = SUBSTRING_INDEX( s.username, '.', 1 )
AND UNIX_TIMESTAMP(s.time) >IFNULL((SELECT MAX(b.time) FROM " . $this->block->getTableName() . " AS b),0)
GROUP BY u.id");
if ($stmt && $stmt->execute() && $result = $stmt->get_result())
@ -183,10 +194,10 @@ class Statistics {
if ($this->getGetCache() && $data = $this->memcache->get(__FUNCTION__ . $account_id)) return $data;
$stmt = $this->mysqli->prepare("
SELECT
SUM(IF(our_result='Y', 1, 0)) AS valid,
SUM(IF(our_result='N', 1, 0)) AS invalid
IFNULL(SUM(IF(our_result='Y', 1, 0)), 0) AS valid,
IFNULL(SUM(IF(our_result='N', 1, 0)), 0) AS invalid
FROM " . $this->share->getTableName() . " AS s,
" . $this->user->getTableName() . " AS u
" . $this->user->getTableName() . " AS u
WHERE
u.username = SUBSTRING_INDEX( s.username, '.', 1 )
AND UNIX_TIMESTAMP(s.time) >IFNULL((SELECT MAX(b.time) FROM " . $this->block->getTableName() . " AS b),0)
@ -220,8 +231,7 @@ class Statistics {
WHERE
a.username LIKE ?
GROUP BY username
ORDER BY username
");
ORDER BY username");
if ($this->checkStmt($stmt) && $stmt->bind_param('s', $filter) && $stmt->execute() && $result = $stmt->get_result()) {
return $this->memcache->setCache(__FUNCTION__ . $filter, $result->fetch_all(MYSQLI_ASSOC));
}
@ -236,13 +246,24 @@ class Statistics {
$this->debug->append("STA " . __METHOD__, 4);
if ($data = $this->memcache->get(__FUNCTION__ . $account_id)) return $data;
$stmt = $this->mysqli->prepare("
SELECT ROUND(COUNT(s.id) * POW(2, " . $this->config['difficulty'] . ")/600/1000) AS hashrate
FROM " . $this->share->getTableName() . " AS s,
" . $this->user->getTableName() . " AS u
WHERE u.username = SUBSTRING_INDEX( s.username, '.', 1 )
AND s.time > DATE_SUB(now(), INTERVAL 10 MINUTE)
AND u.id = ?");
if ($this->checkStmt($stmt) && $stmt->bind_param("i", $account_id) && $stmt->execute() && $result = $stmt->get_result() )
SELECT
(
SELECT IFNULL(ROUND(COUNT(s.id) * POW(2, " . $this->config['difficulty'] . ") / 600 / 1000), 0) AS hashrate
FROM " . $this->share->getTableName() . " AS s,
" . $this->user->getTableName() . " AS u
WHERE u.username = SUBSTRING_INDEX( s.username, '.', 1 )
AND s.time > DATE_SUB(now(), INTERVAL 10 MINUTE)
AND u.id = ?
) + (
SELECT IFNULL(ROUND(COUNT(s.id) * POW(2, " . $this->config['difficulty'] . ") / 600 / 1000), 0) AS hashrate
FROM " . $this->share->getArchiveTableName() . " AS s,
" . $this->user->getTableName() . " AS u
WHERE u.username = SUBSTRING_INDEX( s.username, '.', 1 )
AND s.time > DATE_SUB(now(), INTERVAL 10 MINUTE)
AND u.id = ?
) AS hashrate
FROM DUAL");
if ($this->checkStmt($stmt) && $stmt->bind_param("ii", $account_id, $account_id) && $stmt->execute() && $result = $stmt->get_result() )
return $this->memcache->setCache(__FUNCTION__ . $account_id, $result->fetch_object()->hashrate);
// Catchall
$this->debug->append("Failed to fetch hashrate: " . $this->mysqli->error);
@ -280,7 +301,7 @@ class Statistics {
$this->debug->append("STA " . __METHOD__, 4);
if ($data = $this->memcache->get(__FUNCTION__ . $worker_id)) return $data;
$stmt = $this->mysqli->prepare("
SELECT ROUND(COUNT(s.id) * POW(2,21)/600/1000) AS hashrate
SELECT IFNULL(ROUND(COUNT(s.id) * POW(2,21)/600/1000), 0) AS hashrate
FROM " . $this->share->getTableName() . " AS s,
" . $this->user->getTableName() . " AS u
WHERE u.username = SUBSTRING_INDEX( s.username, '.', 1 )
@ -306,8 +327,8 @@ class Statistics {
case 'shares':
$stmt = $this->mysqli->prepare("
SELECT
COUNT(id) AS shares,
SUBSTRING_INDEX( username, '.', 1 ) AS account
COUNT(id) AS shares,
SUBSTRING_INDEX( username, '.', 1 ) AS account
FROM " . $this->share->getTableName() . "
WHERE our_result = 'Y'
GROUP BY account
@ -322,11 +343,14 @@ class Statistics {
case 'hashes':
$stmt = $this->mysqli->prepare("
SELECT
ROUND(COUNT(id) * POW(2," . $this->config['difficulty'] . ")/600/1000,2) AS hashrate,
IFNULL(ROUND(COUNT(id) * POW(2," . $this->config['difficulty'] . ")/600/1000, 2), 0) AS hashrate,
SUBSTRING_INDEX( username, '.', 1 ) AS account
FROM " . $this->share->getTableName() . "
WHERE time > DATE_SUB(now(), INTERVAL 10 MINUTE)
AND our_result = 'Y'
FROM
(
SELECT id, username FROM " . $this->share->getTableName() . " WHERE time > DATE_SUB(now(), INTERVAL 10 MINUTE) AND our_result = 'Y'
UNION
SELECT id, username FROM " . $this->share->getArchiveTableName() ." WHERE time > DATE_SUB(now(), INTERVAL 10 MINUTE) AND our_result = 'Y'
) AS t1
GROUP BY account
ORDER BY hashrate DESC LIMIT ?");
if ($this->checkStmt($stmt) && $stmt->bind_param("i", $limit) && $stmt->execute() && $result = $stmt->get_result())
@ -347,15 +371,14 @@ class Statistics {
if ($data = $this->memcache->get(__FUNCTION__ . $account_id)) return $data;
$stmt = $this->mysqli->prepare("
SELECT
ROUND(COUNT(s.id) * POW(2, " . $this->config['difficulty'] . ") / 3600 / 1000) AS hashrate,
ROUND(COUNT(s.id) * POW(2, " . $this->config['difficulty'] . ") / 3600 / 1000) AS hashrate,
HOUR(s.time) AS hour
FROM " . $this->share->getTableName() . " AS s, accounts AS a
WHERE time < NOW() - INTERVAL 1 HOUR
AND time > NOW() - INTERVAL 25 HOUR
AND a.username = SUBSTRING_INDEX( s.username, '.', 1 )
AND a.id = ?
GROUP BY HOUR(time)
");
GROUP BY HOUR(time)");
if ($this->checkStmt($stmt) && $stmt->bind_param("i", $account_id) && $stmt->execute() && $result = $stmt->get_result()) {
$aData = array();
while ($row = $result->fetch_assoc()) {
@ -367,7 +390,7 @@ class Statistics {
$this->debug->append("Failed to fetch hourly hashrate: " . $this->mysqli->error);
return false;
}
/**
* get Hourly hashrate for the pool
* @param none
@ -378,13 +401,12 @@ class Statistics {
if ($this->getGetCache() && $data = $this->memcache->get(__FUNCTION__)) return $data;
$stmt = $this->mysqli->prepare("
SELECT
ROUND(COUNT(s.id) * POW(2, " . $this->config['difficulty'] . ") / 3600 / 1000) AS hashrate,
IFNULL(ROUND(COUNT(s.id) * POW(2, " . $this->config['difficulty'] . ") / 3600 / 1000), 0) AS hashrate,
HOUR(s.time) AS hour
FROM " . $this->share->getTableName() . " AS s
WHERE time < NOW() - INTERVAL 1 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()) {
while ($row = $result->fetch_assoc()) {
$aData[$row['hour']] = $row['hashrate'];

View File

@ -282,14 +282,20 @@ class User {
$bUser = false;
// number validation checks
if ($threshold < $this->config['ap_threshold']['min'] && $threshold != 0) {
if (!is_numeric($threshold)) {
$this->setErrorMessage('Invalid input for auto-payout');
return false;
} else if ($threshold < $this->config['ap_threshold']['min'] && $threshold != 0) {
$this->setErrorMessage('Threshold below configured minimum of ' . $this->config['ap_threshold']['min']);
return false;
} else if ($threshold > $this->config['ap_threshold']['max']) {
$this->setErrorMessage('Threshold above configured maximum of ' . $this->config['ap_threshold']['max']);
return false;
}
if ($donate < 0) {
if (!is_numeric($donate)) {
$this->setErrorMessage('Invalid input for donation');
return false;
} else if ($donate < 0) {
$this->setErrorMessage('Donation below allowed 0% limit');
return false;
} else if ($donate > 100) {
@ -449,7 +455,6 @@ class User {
$this->setErrorMessage( 'Invalid PIN' );
return false;
}
$apikey = hash("sha256",$username.$salt);
if ($this->mysqli->query("SELECT id FROM $this->table LIMIT 1")->num_rows > 0) {
$stmt = $this->mysqli->prepare("
INSERT INTO $this->table (username, pass, email, pin, api_key)
@ -461,12 +466,16 @@ class User {
VALUES (?, ?, ?, ?, ?, 1)
");
}
if ($this->checkStmt($stmt)) {
$stmt->bind_param('sssss', $username, hash("sha256", $password1.$this->salt), $email1, hash("sha256", $pin.$this->salt), $apikey);
// Create hashed strings using original string and salt
$password_hash = hash('sha256', $password1.$this->salt);
$pin_hash = hash('sha256', $pin.$this->salt);
$apikey_hash = hash('sha256', $username.$this->salt);
if ($this->checkStmt($stmt) && $stmt->bind_param('sssss', $username, $password_hash, $email1, $pin_hash, $apikey_hash)) {
if (!$stmt->execute()) {
$this->setErrorMessage( 'Unable to register' );
if ($stmt->sqlstate == '23000') $this->setErrorMessage( 'Username already exists' );
echo $this->mysqli->error;
return false;
}
$stmt->close();
@ -514,6 +523,10 @@ class User {
public function resetPassword($username, $smarty) {
$this->debug->append("STA " . __METHOD__, 4);
// Fetch the users mail address
if (empty($username)) {
$this->serErrorMessage("Username must not be empty");
return false;
}
if (!$email = $this->getUserEmail($username)) {
$this->setErrorMessage("Unable to find a mail address for user $username");
return false;

View File

@ -42,14 +42,22 @@ class Worker {
**/
public function updateWorkers($account_id, $data) {
$this->debug->append("STA " . __METHOD__, 4);
if (!is_array($data)) {
$this->setErrorMessage('No workers to update');
return false;
}
$username = $this->user->getUserName($account_id);
$iFailed = 0;
foreach ($data as $key => $value) {
// Prefix the WebUser to Worker name
$value['username'] = "$username." . $value['username'];
$stmt = $this->mysqli->prepare("UPDATE $this->table SET password = ?, username = ?, monitor = ? WHERE account_id = ? AND id = ?");
if ( ! ( $this->checkStmt($stmt) && $stmt->bind_param('ssiii', $value['password'], $value['username'], $value['monitor'], $account_id, $key) && $stmt->execute()) )
if ('' === $value['username'] || '' === $value['password']) {
$iFailed++;
} else {
// Prefix the WebUser to Worker name
$value['username'] = "$username." . $value['username'];
$stmt = $this->mysqli->prepare("UPDATE $this->table SET password = ?, username = ?, monitor = ? WHERE account_id = ? AND id = ?");
if ( ! ( $this->checkStmt($stmt) && $stmt->bind_param('ssiii', $value['password'], $value['username'], $value['monitor'], $account_id, $key) && $stmt->execute()) )
$iFailed++;
}
}
if ($iFailed == 0)
return true;
@ -150,6 +158,10 @@ class Worker {
**/
public function addWorker($account_id, $workerName, $workerPassword) {
$this->debug->append("STA " . __METHOD__, 4);
if ('' === $workerName || '' === $workerPassword) {
$this->setErrorMessage('Worker name and/or password may not be empty');
return false;
}
$username = $this->user->getUserName($account_id);
$workerName = "$username.$workerName";
$stmt = $this->mysqli->prepare("INSERT INTO $this->table (account_id, username, password) VALUES(?, ?, ?)");
@ -177,7 +189,6 @@ class Worker {
if ($this->checkStmt($stmt)) {
$stmt->bind_param('ii', $account_id, $id);
if ($stmt->execute() && $stmt->affected_rows == 1) {
$stmt->close;
return true;
} else {
$this->setErrorMessage( 'Unable to delete worker' );

View File

@ -161,9 +161,11 @@ $config['payout_system'] = 'prop';
$config['archive_shares'] = true;
// URL prefix for block searches, used for block links, default: `http://explorer.litecoin.net/search?q=`
// If empty, the block link to the block information page will be removed
$config['blockexplorer'] = 'http://explorer.litecoin.net/search?q=';
// Link to blockchain information, used for difficulty link, default: `http://allchains.info`
// If empty, the difficulty link to the chain information will be removed
$config['chaininfo'] = 'http://allchains.info';
// Pool fees applied to users in percent, default: 0 (disabled)
@ -177,18 +179,39 @@ $config['difficulty'] = 20;
/**
* This defines how rewards are paid to users.
*
* Explanation:
*
* Proportional Payout System
* When running a pool on fixed mode, each block will be paid
* out as defined in `reward`. If you wish to pass transaction
* fees inside discovered blocks on to user, set this to `block`.
* This is really helpful for altcoins with dynamic block values!
*
* PPS Payout System
* If set to `fixed`, all PPS values are based on the `reward` setting.
* If you set it to `block` you will calculate the current round based
* on the previous block value. The idea is to pass the block of the
* last round on to the users. If no previous block is found, PPS value
* will fall back to the fixed value set in `reward`. Ensure you don't
* overpay users in the first round!
*
* Available options:
* reward_type:
* fixed : Fixed value according to `reward` setting
* block : Dynamic value based on block amount
* reward:
* float value : Any value of your choice but should reflect base block values
*
* Default:
* fixed
* reward_type = `fixed`
* reward = 50
*
**/
$config['reward_type'] = 'fixed';
$config['reward'] = 50;
// Confirmations per block required to credit transactions, default: 120
$config['confirmations'] = 5;
$config['confirmations'] = 120;
/**
@ -213,7 +236,7 @@ $config['confirmations'] = 5;
* expiration = 90
* splay = 15
**/
$config['memcache']['enabled'] = false;
$config['memcache']['enabled'] = true;
$config['memcache']['host'] = 'localhost';
$config['memcache']['port'] = 11211;
$config['memcache']['keyprefix'] = 'mmcfe_ng_';

View File

@ -1,5 +1,4 @@
<?php
// Make sure we are called from index.php
if (!defined('SECURITY')) die('Hacking attempt');
@ -20,7 +19,7 @@ if ($user->isAuthenticated()) {
}
break;
case 'update':
if ($worker->updateWorkers($_SESSION['USERDATA']['id'], $_POST['data'])) {
if ($worker->updateWorkers($_SESSION['USERDATA']['id'], @$_POST['data'])) {
$_SESSION['POPUP'][] = array('CONTENT' => 'Worker updated');
} else {
$_SESSION['POPUP'][] = array('CONTENT' => $worker->getError(), 'TYPE' => 'errormsg');

View File

@ -0,0 +1,60 @@
<?php
// Make sure we are called from index.php
if (!defined('SECURITY')) die('Hacking attempt');
// Check user token
$user_id = $user->checkApiKey($_REQUEST['api_key']);
// Fetch last block information
$aLastBlock = $block->getLast();
// Efficiency
$aShares = $statistics->getRoundShares();
$aShares['valid'] > 0 ? $dEfficiency = round((100 - (100 / $aShares['valid'] * $aShares['invalid'])), 2) : $dEfficiency = 0;
// Fetch RPC data
if ($bitcoin->can_connect() === true){
$dDifficulty = $bitcoin->getdifficulty();
if (is_array($dDifficulty) && array_key_exists('proof-of-work', $dDifficulty))
$dDifficulty = $dDifficulty['proof-of-work'];
$iBlock = $bitcoin->getblockcount();
} else {
$dDifficulty = 1;
$iBlock = 0;
}
// Estimated time to find the next block
$iCurrentPoolHashrate = $statistics->getCurrentHashrate();
// Time in seconds, not hours, using modifier in smarty to translate
$iCurrentPoolHashrate > 0 ? $iEstTime = $dDifficulty * pow(2,32) / ($iCurrentPoolHashrate * 1000) : $iEstTime = 0;
$iEstShares = (pow(2, 32 - $config['difficulty']) * $dDifficulty);
// Time since last
$now = new DateTime( "now" );
if (!empty($aLastBlock)) {
$dTimeSinceLast = ($now->getTimestamp() - $aLastBlock['time']);
} else {
$dTimeSinceLast = 0;
}
// Output JSON format
echo json_encode(
array(
'getpoolstatus' => array(
'hashrate' => $iCurrentPoolHashrate,
'efficiency' => $dEfficiency,
'workers' => $worker->getCountAllActiveWorkers(),
'currentnetworkblock' => $iBlock,
'nextnetworkblock' => $iBlock + 1,
'lastblock' => $aLastBlock['height'],
'networkdiff' => $dDifficulty,
'esttime' => $iEstTime,
'estshares' => $iEstShares,
'timesincelast' => $dTimeSinceLast,
)));
// Supress master template
$supress_master = 1;
?>

View File

@ -8,9 +8,11 @@ use \Michelf\Markdown;
// Fetch active news to display
$aNews = $news->getAllActive();
foreach ($aNews as $key => $aData) {
// Transform Markdown content to HTML
$aNews[$key]['content'] = Markdown::defaultTransform($aData['content']);
if (is_array($aNews)) {
foreach ($aNews as $key => $aData) {
// Transform Markdown content to HTML
$aNews[$key]['content'] = Markdown::defaultTransform($aData['content']);
}
}
// Load news entries for Desktop site and unauthenticated users

View File

@ -8,9 +8,11 @@ use \Michelf\Markdown;
// Fetch active news to display
$aNews = $news->getAllActive();
foreach ($aNews as $key => $aData) {
// Transform Markdown content to HTML
$aNews[$key]['content'] = Markdown::defaultTransform($aData['content']);
if (is_array($aNews)) {
foreach ($aNews as $key => $aData) {
// Transform Markdown content to HTML
$aNews[$key]['content'] = Markdown::defaultTransform($aData['content']);
}
}
// Tempalte specifics

View File

@ -29,10 +29,9 @@ count($aBlocksFoundData) > 0 ? $aBlockData = $aBlocksFoundData[0] : $aBlockData
// Estimated time to find the next block
$iCurrentPoolHashrate = $statistics->getCurrentHashrate();
$iCurrentPoolHashrate == 0 ? $iCurrentPoolHashrate = 1 : true;
// Time in seconds, not hours, using modifier in smarty to translate
$iEstTime = $dDifficulty * pow(2,32) / ($iCurrentPoolHashrate * 1000);
$iCurrentPoolHashrate > 0 ? $iEstTime = $dDifficulty * pow(2,32) / ($iCurrentPoolHashrate * 1000) : $iEstTime = 0;
// Time since last block
$now = new DateTime( "now" );

View File

@ -18,15 +18,19 @@ if (@$_SESSION['AUTHENTICATED']) {
$dDifficulty = $bitcoin->query('getdifficulty');
if (is_array($dDifficulty) && array_key_exists('proof-of-work', $dDifficulty))
$dDifficulty = $dDifficulty['proof-of-work'];
$dNetworkHashrate = $bitcoin->query('getnetworkhashps');
}
}
// Always fetch this since we need for ministats header
$bitcoin->can_connect() === true ? $dNetworkHashrate = $bitcoin->query('getnetworkhashps') : $dNetworkHashrate = 0;
// Fetch some data
$iCurrentActiveWorkers = $worker->getCountAllActiveWorkers();
$iCurrentPoolHashrate = $statistics->getCurrentHashrate();
$iCurrentPoolShareRate = $statistics->getCurrentShareRate();
// Avoid confusion, ensure our nethash isn't higher than poolhash
if ($iCurrentPoolHashrate > $dNetworkHashrate) $dNetworkHashrate = $iCurrentPoolHashrate;
// Global data for Smarty
$aGlobal = array(
'slogan' => $config['website']['slogan'],
@ -34,7 +38,6 @@ $aGlobal = array(
'hashrate' => $iCurrentPoolHashrate,
'nethashrate' => $dNetworkHashrate,
'sharerate' => $iCurrentPoolShareRate,
'ppsvalue' => number_format(round(50 / (pow(2,32) * $dDifficulty) * pow(2, $config['difficulty']), 12) ,12),
'workers' => $iCurrentActiveWorkers,
'roundshares' => $aRoundShares,
'fees' => $config['fees'],
@ -57,6 +60,18 @@ $aGlobal = array(
)
);
// Special calculations for PPS Values based on reward_type setting and/or available blocks
if ($config['reward_type'] != 'block') {
$aGlobal['ppsvalue'] = number_format(round(50 / (pow(2,32) * $dDifficulty) * pow(2, $config['difficulty']), 12) ,12);
} else {
// Try to find the last block value and use that for future payouts, revert to fixed reward if none found
if ($aLastBlock = $block->getLast()) {
$aGlobal['ppsvalue'] = number_format(round($aLastBlock['amount'] / (pow(2,32) * $dDifficulty) * pow(2, $config['difficulty']), 12) ,12);
} else {
$aGlobal['ppsvalue'] = number_format(round($config['reward'] / (pow(2,32) * $dDifficulty) * pow(2, $config['difficulty']), 12) ,12);
}
}
// We don't want these session infos cached
if (@$_SESSION['USERDATA']['id']) {
$aGlobal['userdata'] = $_SESSION['USERDATA']['id'] ? $user->getUserData($_SESSION['USERDATA']['id']) : array();
@ -73,10 +88,10 @@ if (@$_SESSION['USERDATA']['id']) {
default:
// Some estimations
if (@$aRoundShares['valid'] > 0) {
$aGlobal['userdata']['est_block'] = round(( (int)$aGlobal['userdata']['shares']['valid'] / (int)$aRoundShares['valid'] ) * (int)$config['reward'], 3);
$aGlobal['userdata']['est_fee'] = round(($config['fees'] / 100) * $aGlobal['userdata']['est_block'], 3);
$aGlobal['userdata']['est_donation'] = round((( $aGlobal['userdata']['donate_percent'] / 100) * ($aGlobal['userdata']['est_block'] - $aGlobal['userdata']['est_fee'])), 3);
$aGlobal['userdata']['est_payout'] = round($aGlobal['userdata']['est_block'] - $aGlobal['userdata']['est_donation'] - $aGlobal['userdata']['est_fee'], 3);
$aGlobal['userdata']['est_block'] = round(( (int)$aGlobal['userdata']['shares']['valid'] / (int)$aRoundShares['valid'] ) * (float)$config['reward'], 8);
$aGlobal['userdata']['est_fee'] = round(((float)$config['fees'] / 100) * (float)$aGlobal['userdata']['est_block'], 8);
$aGlobal['userdata']['est_donation'] = round((( (float)$aGlobal['userdata']['donate_percent'] / 100) * ((float)$aGlobal['userdata']['est_block'] - (float)$aGlobal['userdata']['est_fee'])), 8);
$aGlobal['userdata']['est_payout'] = round((float)$aGlobal['userdata']['est_block'] - (float)$aGlobal['userdata']['est_donation'] - (float)$aGlobal['userdata']['est_fee'], 8);
} else {
$aGlobal['userdata']['est_block'] = 0;
$aGlobal['userdata']['est_fee'] = 0;

View File

@ -6,7 +6,7 @@
<table>
<tbody><tr><td>Username: </td><td>{$GLOBAL.userdata.username}</td></tr>
<tr><td>User Id: </td><td>{$GLOBAL.userdata.id}</td></tr>
<tr><td>API Key: </td><td>{$GLOBAL.userdata.api_key}</td></tr>
<tr><td>API Key: </td><td><a href="{$smarty.server.PHP_SELF}?page=api&action=getuserstatus&api_key={$GLOBAL.userdata.api_key}&id={$GLOBAL.userdata.id}">{$GLOBAL.userdata.api_key}</a></td></tr>
<tr><td>E-Mail: </td><td><input type="text" name="email" value="{$GLOBAL.userdata.email|escape}" size="20"></td></tr>
<tr><td>Payment Address: </td><td><input type="text" name="paymentAddress" value="{$smarty.request.paymentAddress|default:$GLOBAL.userdata.coin_address|escape}" size="40"></td></tr>
<tr><td>Donation %: </td><td><input type="text" name="donatePercent" value="{$smarty.request.donatePercent|default:$GLOBAL.userdata.donate_percent|escape}" size="4"><font size="1"> [donation amount in percent (example: 0.5)]</font></td></tr>

View File

@ -14,6 +14,7 @@
</tr>
</thead>
<tbody style="font-size:12px;">
{assign var=has_confirmed value=false}
{section transaction $TRANSACTIONS}
{if (
(($TRANSACTIONS[transaction].type == 'Credit' or $TRANSACTIONS[transaction].type == 'Bonus')and $TRANSACTIONS[transaction].confirmations >= $GLOBAL.confirmations)
@ -26,6 +27,7 @@
or $TRANSACTIONS[transaction].type == 'Debit_MP'
or $TRANSACTIONS[transaction].type == 'TXFee'
)}
{assign var=has_credits value=true}
<tr class="{cycle values="odd,even"}">
<td>{$TRANSACTIONS[transaction].id}</td>
<td>{$TRANSACTIONS[transaction].timestamp}</td>
@ -36,6 +38,9 @@
</tr>
{/if}
{/section}
{if !$has_confirmed}
<tr><td class="center" colspan="6"><b><i>No data</i></b></td></tr>
{/if}
</tbody>
</table>
<p>
@ -60,12 +65,14 @@
</tr>
</thead>
<tbody style="font-size:12px;">
{assign var=has_unconfirmed value=false}
{section transaction $TRANSACTIONS}
{if (
($TRANSACTIONS[transaction].type == 'Credit' or $TRANSACTIONS[transaction].type == 'Bonus') and $TRANSACTIONS[transaction].confirmations < $GLOBAL.confirmations
or ($TRANSACTIONS[transaction].type == 'Donation' and $TRANSACTIONS[transaction].confirmations < $GLOBAL.confirmations)
or ($TRANSACTIONS[transaction].type == 'Fee' and $TRANSACTIONS[transaction].confirmations < $GLOBAL.confirmations)
)}
{assign var=has_unconfirmed value=true}
<tr class="{cycle values="odd,even"}">
<td>{$TRANSACTIONS[transaction].id}</td>
<td>{$TRANSACTIONS[transaction].timestamp}</td>
@ -75,12 +82,15 @@
<td><font color="{if $TRANSACTIONS[transaction].type == 'Credit' or $TRANSACTIONS[transaction].type == 'Bonus'}green{else}red{/if}">{$TRANSACTIONS[transaction].amount|number_format:"8"}</td>
</tr>
{if $TRANSACTIONS[transaction].type == 'Credit' or $TRANSACTIONS[transaction].type == 'Bonus'}
{assign var="credits" value="`$credits+$TRANSACTIONS[transaction].amount`"}
{assign var="credits" value="`$credits|default:"0"+$TRANSACTIONS[transaction].amount`"}
{else}
{assign var="debits" value="`$debits+$TRANSACTIONS[transaction].amount`"}
{assign var="debits" value="`$debits|default:"0"+$TRANSACTIONS[transaction].amount`"}
{/if}
{/if}
{/section}
{if !$has_unconfirmed}
<tr><td class="center" colspan="6"><b><i>No data</i></b></td></tr>
{/if}
<tr>
<td colspan="5"><b>Unconfirmed Totals:</b></td>
<td><b>{($credits|default - $debits|default)|number_format:"8"}</b></td>
@ -105,6 +115,7 @@
</tr>
</thead>
<tbody style="font-size:12px;">
{assign var=has_orphaned value=false}
{section transaction $TRANSACTIONS}
{if (
$TRANSACTIONS[transaction].type == 'Orphan_Credit'
@ -121,12 +132,15 @@
<td><font color="{if $TRANSACTIONS[transaction].type == 'Orphan_Credit' or $TRANSACTIONS[transaction].type == 'Orphan_Bonus'}green{else}red{/if}">{$TRANSACTIONS[transaction].amount|number_format:"8"}</td>
</tr>
{if $TRANSACTIONS[transaction].type == 'Orphan_Credit' or $TRANSACTIONS[transaction].type == 'Orphan_Bonus'}
{assign var="orphan_credits" value="`$orphan_credits+$TRANSACTIONS[transaction].amount`"}
{assign var="orphan_credits" value="`$orphan_credits|default:"0"+$TRANSACTIONS[transaction].amount`"}
{else}
{assign var="orphan_debits" value="`$orphan_debits+$TRANSACTIONS[transaction].amount`"}
{assign var="orphan_debits" value="`$orphan_debits|default:"0"+$TRANSACTIONS[transaction].amount`"}
{/if}
{/if}
{/section}
{if !$has_orphaned}
<tr><td class="center" colspan="6"><b><i>No data</i></b></td></tr>
{/if}
<tr>
<td colspan="5"><b>Orphaned Totals:</b></td>
<td><b>{($orphan_credits|default - $orphan_debits|default)|number_format:"8"}</b></td>

View File

@ -18,8 +18,8 @@
{section worker $WORKERS}
{assign var="username" value="."|escape|explode:$WORKERS[worker].username:2}
<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" /></td>
<td><input type="text" name="data[{$WORKERS[worker].id}][password]" value="{$WORKERS[worker].password|escape}" size="10"></td>
<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><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">
<input type="checkbox" name="data[{$WORKERS[worker].id}][monitor]" value="1" id="data[{$WORKERS[worker].id}][monitor]" {if $WORKERS[worker].monitor}checked{/if} />
@ -43,7 +43,7 @@
<input type="hidden" name="page" value="{$smarty.request.page}">
<input type="hidden" name="action" value="{$smarty.request.action}">
<input type="hidden" name="do" value="add">
{$smarty.session.USERDATA.username}.<input type="text" name="username" value="user" size="10" maxlength="20"> · <input type="text" name="password" value="password" size="10" maxlength="20">&nbsp;<input type="submit" value="Add New Worker" style="padding:5px;">
{$smarty.session.USERDATA.username}.<input type="text" name="username" value="user" size="10" maxlength="20" required> · <input type="text" name="password" value="password" size="10" maxlength="20" required>&nbsp;<input type="submit" value="Add New Worker" style="padding:5px;">
</form>
</center>
{include file="global/block_footer.tpl"}

View File

@ -5,7 +5,7 @@
<table border="0">
<tr>
{if $GLOBAL.config.price.currency}<td><li>{$GLOBAL.config.currency}/{$GLOBAL.config.price.currency}: {$GLOBAL.price|default:"n/a"|number_format:"4"}&nbsp;&nbsp;&nbsp;&nbsp;</li></td>{/if}
<td><li>Network Hashrate: {($GLOBAL.nethashrate / 1000 / 1000 / 1000)|number_format:"3"} GH/s&nbsp;&nbsp;&nbsp;&nbsp;</li></td>
<td><li>Network Hashrate: {($GLOBAL.nethashrate / 1000 / 1000 )|default:"0"|number_format:"3"} MH/s&nbsp;&nbsp;&nbsp;&nbsp;</li></td>
<td><li>Pool Hashrate: {($GLOBAL.hashrate / 1000)|number_format:"3"} MH/s&nbsp;&nbsp;&nbsp;&nbsp;</li></td>
<td><li>Pool Sharerate: {$GLOBAL.sharerate|number_format:"2"} Shares/s&nbsp;&nbsp;&nbsp;&nbsp;</li></td>
<td><li>Pool Workers: {$GLOBAL.workers}&nbsp;&nbsp;&nbsp;&nbsp;</li></td>

View File

@ -1,7 +1,7 @@
<ul id="nav">
<li><a href="{$smarty.server.PHP_SELF}">Home</a></li>
{if $smarty.session.AUTHENTICATED|default:"0" == 1}
<li><a href="">My Account</a>
<li><a href="{$smarty.server.PHP_SELF}?page=account&action=edit">My Account</a>
<ul>
<li><a href="{$smarty.server.PHP_SELF}?page=account&action=edit">Edit Account</a></li>
<li><a href="{$smarty.server.PHP_SELF}?page=account&action=workers">My Workers</a></li>

View File

@ -44,19 +44,19 @@
</tr>
<tr>
<td><b>Block</b></td>
<td class="right">{$GLOBAL.userdata.est_block|number_format:"3"}</td>
<td class="right">{$GLOBAL.userdata.est_block|number_format:"8"}</td>
</tr>
<tr>
<td><b>Fees</b></td>
<td class="right">{$GLOBAL.userdata.est_fee|number_format:"3"}</td>
<td class="right">{$GLOBAL.userdata.est_fee|number_format:"8"}</td>
</tr>
<tr>
<td><b>Donation</b></td>
<td class="right">{$GLOBAL.userdata.est_donation|number_format:"3"}</td>
<td class="right">{$GLOBAL.userdata.est_donation|number_format:"8"}</td>
</tr>
<tr>
<td><b>Payout</b></td>
<td class="right">{$GLOBAL.userdata.est_payout|number_format:"3"}</td>
<td class="right">{$GLOBAL.userdata.est_payout|number_format:"8"}</td>
</tr>
<tr><td colspan="2">&nbsp;</td></tr>
<tr><td colspan="2"><b><u>{$GLOBAL.config.currency} Account Balance</u></b></td></tr>

View File

@ -3,6 +3,6 @@
<input type="hidden" name="page" value="password">
<input type="hidden" name="action" value="reset">
<p>If you have an email set for your account, enter your username to get your password reset</p>
<p><input type="text" value="{$smarty.post.username}" name="username"><input class="submit small" type="submit" value="Reset"></p>
<p><input type="text" value="{$smarty.post.username|default:""}" name="username" required><input class="submit small" type="submit" value="Reset"></p>
</form>
{include file="global/block_footer.tpl"}

View File

@ -10,7 +10,7 @@
<tr><td>Email:</td><td><input type="text" name="email1" class="text small" value="{$smarty.post.email1|escape|default:""}" size="15" required></td></tr>
<tr><td>Email Repeat:</td><td><input type="text" class="text small" name="email2" value="{$smarty.post.email2|escape|default:""}" size="15" required></td></tr>
<tr><td>PIN:</td><td><input type="password" class="text pin" name="pin" value="" size="4" maxlength="4"><font size="1"> (4 digit number. <b>Remember this pin!</b>)</font></td></tr>
<tr><td colspan="2">{nocache}{$RECAPTCHA}{/nocache}</td></tr>
<tr><td colspan="2">{nocache}{$RECAPTCHA|default:""}{/nocache}</td></tr>
<tr><td class="center"><input type="submit" class="submit small" value="Register"></td><td></td></tr>
</tbody>
</table>

View File

@ -4,7 +4,7 @@
{include file="statistics/pool/contributors_hashrate.tpl"}
{include file="global/block_header.tpl" ALIGN="left" BLOCK_HEADER="Server Stats" BLOCK_STYLE="clear:all;" STYLE="padding-left:5px;padding-right:5px;"}
{include file="global/block_header.tpl" ALIGN="left" BLOCK_HEADER="Server Stats" BLOCK_STYLE="clear:both;" STYLE="padding-left:5px;padding-right:5px;"}
<table class="" width="100%" style="font-size:13px;">
<tbody>
<tr>
@ -19,17 +19,28 @@
<td class="leftheader">Current Active Workers</td>
<td>{$GLOBAL.workers}</td>
</tr>
{if $GLOBAL.blockexplorer}
<tr>
<td class="leftheader">Next Network Block</td>
<td><a href="{$GLOBAL.blockexplorer}{$CURRENTBLOCK + 1}" target="_new">{$CURRENTBLOCK + 1}</a> &nbsp;&nbsp;<font size="1"> (Current: <a href="{$GLOBAL.blockexplorer}{$CURRENTBLOCK}" target="_new">{$CURRENTBLOCK})</a></font></td>
</tr>
{else}
<tr>
<td class="leftheader">Next Network Block</td>
<td>{$CURRENTBLOCK + 1} &nbsp;&nbsp; (Current: {$CURRENTBLOCK})</td>
</tr>
{/if}
<tr>
<td class="leftheader">Last Block Found</td>
<td><a href="{$GLOBAL.blockexplorer}{$LASTBLOCK}" target="_new">{$LASTBLOCK|default:"0"}</a></td>
<td>{if $GLOBAL.blockexplorer}<a href="{$GLOBAL.blockexplorer}{$LASTBLOCK}" target="_new">{$LASTBLOCK|default:"0"}</a>{else}{$LASTBLOCK|default:"0"}{/if}</td>
</tr>
<tr>
<td class="leftheader">Current Difficulty</td>
{if $GLOBAL.chaininfo}
<td><a href="{$GLOBAL.chaininfo}" target="_new"><font size="2">{$DIFFICULTY}</font></a></td>
{else}
<td><font size="2">{$DIFFICULTY}</font></td>
{/if}
</tr>
<tr>
<td class="leftheader">Est. Avg. Time per Round</td>
@ -45,6 +56,7 @@
</tr>
</tbody>
</table>
<li>These stats are also available in JSON format <a href="{$smarty.server.PHP_SELF}?page=api&action=getpoolstatus&api_key={$GLOBAL.userdata.api_key}">HERE</a></li>
{include file="global/block_footer.tpl"}

View File

@ -33,22 +33,22 @@
</tr>
<tr>
<td><b>Block</b></td>
<td align="right">{$GLOBAL.userdata.est_block|number_format:"3"}</td>
<td align="right">{$GLOBAL.userdata.est_block|number_format:"8"}</td>
</tr>
<tr>
<td><b>Fees</b></td>
<td align="right">{$GLOBAL.userdata.est_fee|number_format:"3"}</td>
<td align="right">{$GLOBAL.userdata.est_fee|number_format:"8"}</td>
</tr>
<tr>
<td><b>Donation</b></td>
<td align="right">{$GLOBAL.userdata.est_donation|number_format:"3"}</td>
<td align="right">{$GLOBAL.userdata.est_donation|number_format:"8"}</td>
</tr>
<tr>
<td><b>Payout</b></td>
<td align="right">{$GLOBAL.userdata.est_payout|number_format:"3"}</td>
<td align="right">{$GLOBAL.userdata.est_payout|number_format:"8"}</td>
</tr>
<tr><td colspan="2">&nbsp;</td></tr>
<tr><td colspan="2"><b><u>{$GLOBAL.config.currency} Account Balance</u></b></td></tr>
<tr><td>Confirmed</td><td align="right"><b>{$GLOBAL.userdata.balance.confirmed|default:"0"|number_format:"3"}</td></tr>
<tr><td>Unconfirmed</td><td align="right"><b>{$GLOBAL.userdata.balance.unconfirmed|default:"0"|number_format:"3"}</td></tr>
<tr><td>Confirmed</td><td align="right"><b>{$GLOBAL.userdata.balance.confirmed|default:"0"|number_format:"8"}</td></tr>
<tr><td>Unconfirmed</td><td align="right"><b>{$GLOBAL.userdata.balance.unconfirmed|default:"0"|number_format:"8"}</td></tr>
</table>

View File

@ -2,5 +2,5 @@
<input type="hidden" name="page" value="password">
<input type="hidden" name="action" value="reset">
<p>If you have an email set for your account, enter your username to get your password reset</p>
<p><input type="text" value="{$smarty.post.username}" name="username"><input class="submit small" type="submit" value="Reset"></p>
<p><input type="text" value="{$smarty.post.username|default:""}" name="username" required><input class="submit small" type="submit" value="Reset"></p>
</form>

View File

@ -24,18 +24,27 @@
<td class="leftheader">Current Active Workers</td>
<td>{$GLOBAL.workers}</td>
</tr>
{if $GLOBAL.blockexplorer}
<tr>
<td class="leftheader">Next Network Block</td>
<td><a href="{$GLOBAL.blockexplorer}{$CURRENTBLOCK + 1}" target="_new">{$CURRENTBLOCK + 1}</a> &nbsp;&nbsp;<font size="1"> (Current: <a href="{$GLOBAL.blockexplorer}{$CURRENTBLOCK}" target="_new">{$CURRENTBLOCK})</a></font></td>
</tr>
{else}
<tr>
<td class="leftheader">Next Network Block</td>
<td>{$CURRENTBLOCK + 1} &nbsp;&nbsp; (Current: {$CURRENTBLOCK})</td>
</tr>
{/if}
<tr>
<td class="leftheader">Last Block Found</td>
<td><a href="{$GLOBAL.blockexplorer}{$LASTBLOCK}" target="_new">{$LASTBLOCK|default:"0"}</a></td>
<td>{if $GLOBAL.blockexplorer}<a href="{$GLOBAL.blockexplorer}{$LASTBLOCK}" target="_new">{$LASTBLOCK|default:"0"}</a>{else}{$LASTBLOCK|default:"0"}{/if}</td>
</tr>
{if $GLOBAL.chaininfo}
<tr>
<td class="leftheader">Current Difficulty</td>
<td><a href="{$GLOBAL.chaininfo}" target="_new"><font size="2">{$DIFFICULTY}</font></a></td>
</tr>
{/if}
<tr>
<td class="leftheader">Est. Avg. Time per Round</td>
<td>{$ESTTIME|seconds_to_words}</td>

View File

@ -1,17 +0,0 @@
CREATE TABLE IF NOT EXISTS `notifications` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`type` varchar(25) NOT NULL,
`data` varchar(255) NOT NULL,
`active` tinyint(1) NOT NULL DEFAULT '1',
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`account_id` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `active` (`active`),
KEY `data` (`data`),
KEY `account_id` (`account_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `notification_settings` (
`type` varchar(15) NOT NULL,
`account_id` int(11) NOT NULL,
`active` tinyint(1) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

View File

@ -1,2 +0,0 @@
ALTER TABLE `accounts` ADD `is_locked` BOOLEAN NOT NULL DEFAULT FALSE AFTER `email` ;
ALTER TABLE `accounts` CHANGE `admin` `is_admin` BOOLEAN NOT NULL DEFAULT FALSE ;

View File

@ -1 +0,0 @@
ALTER TABLE `transactions` CHANGE `type` `type` ENUM( 'Credit', 'Debit_MP', 'Debit_AP', 'Donation', 'Fee', 'Orphan_Credit', 'Orphan_Fee', 'Orphan_Donation', 'Bonus', 'Orphan_Bonus' ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL;

View File

@ -1 +0,0 @@
ALTER TABLE `settings` CHANGE `setting` `name` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ;

View File

@ -1 +0,0 @@
ALTER TABLE `accounts` ADD `failed_logins` INT( 5 ) UNSIGNED NULL DEFAULT '0' AFTER `is_locked` ;

View File

@ -1 +0,0 @@
ALTER TABLE `transactions` CHANGE `type` `type` ENUM( 'Credit', 'Debit_MP', 'Debit_AP', 'Donation', 'Fee', 'Orphan_Credit', 'Orphan_Fee', 'Orphan_Donation', 'Credit_PPS', 'Fee_PPS', 'Donation_PPS', 'TXFee', 'Bonus') CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ;

View File

@ -1 +0,0 @@
ALTER TABLE `notification_settings` ADD `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST ;

View File

@ -1 +0,0 @@
ALTER TABLE `news` ADD `time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP AFTER `content` ;

View File

@ -1,21 +0,0 @@
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
CREATE TABLE IF NOT EXISTS `news` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`account_id` int(10) unsigned NOT NULL,
`header` varchar(255) NOT NULL,
`content` text NOT NULL,
`active` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

View File

@ -1 +0,0 @@
ALTER TABLE `transactions` CHANGE `type` `type` ENUM( 'Credit', 'Debit_MP', 'Debit_AP', 'Donation', 'Fee', 'Orphan_Credit', 'Orphan_Fee', 'Orphan_Donation', 'Bonus', 'Orphan_Bonus', 'Credit_PPS', 'Debit_PPS', 'Donation_PPS' ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL;