commit
1aff62f636
@ -51,17 +51,17 @@ if (empty($aTransactions['transactions'])) {
|
||||
// Let us add those blocks as unaccounted
|
||||
foreach ($aTransactions['transactions'] as $iIndex => $aData) {
|
||||
if ( $aData['category'] == 'generate' || $aData['category'] == 'immature' ) {
|
||||
$aBlockInfo = $bitcoin->query('getblock', $aData['blockhash']);
|
||||
$aBlockRPCInfo = $bitcoin->query('getblock', $aData['blockhash']);
|
||||
$config['reward_type'] == 'block' ? $aData['amount'] = $aData['amount'] : $aData['amount'] = $config['reward'];
|
||||
$aData['height'] = $aBlockInfo['height'];
|
||||
$aData['difficulty'] = $aBlockInfo['difficulty'];
|
||||
$aData['height'] = $aBlockRPCInfo['height'];
|
||||
$aData['difficulty'] = $aBlockRPCInfo['difficulty'];
|
||||
$log->logInfo(substr($aData['blockhash'], 0, 15) . "...\t" .
|
||||
$aData['height'] . "\t" .
|
||||
$aData['amount'] . "\t" .
|
||||
$aData['confirmations'] . "\t\t" .
|
||||
$aData['difficulty'] . "\t" .
|
||||
strftime("%Y-%m-%d %H:%M:%S", $aData['time']));
|
||||
if ( ! empty($aBlockInfo['flags']) && preg_match('/proof-of-stake/', $aBlockInfo['flags']) ) {
|
||||
if ( ! empty($aBlockRPCInfo['flags']) && preg_match('/proof-of-stake/', $aBlockRPCInfo['flags']) ) {
|
||||
$log->logInfo("Block above with height " . $aData['height'] . " not added to database, proof-of-stake block!");
|
||||
continue;
|
||||
}
|
||||
@ -78,38 +78,65 @@ if (empty($aAllBlocks)) {
|
||||
$log->logDebug('No new blocks without share_id found in database');
|
||||
} else {
|
||||
// Loop through our unaccounted blocks
|
||||
$log->logInfo("Block ID\t\tHeight\tAmount\tShare ID\tShares\tFinder\tType");
|
||||
$log->logInfo("Block ID\tHeight\t\tAmount\tShare ID\tShares\tFinder\t\tType");
|
||||
foreach ($aAllBlocks as $iIndex => $aBlock) {
|
||||
if (empty($aBlock['share_id'])) {
|
||||
// Fetch this blocks upstream ID
|
||||
$aBlockInfo = $bitcoin->query('getblock', $aBlock['blockhash']);
|
||||
if ($share->setUpstream($aBlockInfo, $block->getLastUpstreamId())) {
|
||||
$iCurrentUpstreamId = $share->getUpstreamId();
|
||||
$iAccountId = $user->getUserId($share->getUpstreamFinder());
|
||||
} else {
|
||||
$log->logFatal('Unable to fetch blocks upstream share, aborted:' . $share->getError());
|
||||
$monitoring->setStatus($cron_name . "_active", "yesno", 0);
|
||||
$monitoring->setStatus($cron_name . "_message", "message", "Unable to fetch blocks " . $aBlock['height'] . " upstream share: " . $share->getError());
|
||||
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Fetch share information
|
||||
if (!$iPreviousShareId = $block->getLastShareId()) {
|
||||
$iPreviousShareId = $block->getLastShareId();
|
||||
if ( !$iPreviousShareId && $block->getBlockCount() > 1) {
|
||||
$iPreviousShareId = 0;
|
||||
$log->logInfo('Unable to find highest share ID found so far, if this is your first block, this is normal.');
|
||||
// $log->logError('Unable to find highest share ID found so far, assuming share ID 0 as previous found upstream share.');
|
||||
}
|
||||
$iRoundShares = $share->getRoundShares($iPreviousShareId, $iCurrentUpstreamId);
|
||||
|
||||
// Store new information
|
||||
if (!$block->setShareId($aBlock['id'], $iCurrentUpstreamId))
|
||||
$log->logError('Failed to update share ID in database for block ' . $aBlock['height']);
|
||||
if (!$block->setFinder($aBlock['id'], $iAccountId))
|
||||
$log->logError('Failed to update finder account ID in database for block ' . $aBlock['height']);
|
||||
if (!$block->setShares($aBlock['id'], $iRoundShares))
|
||||
$log->logError('Failed to update share count in database for block ' . $aBlock['height']);
|
||||
if ($config['block_bonus'] > 0 && !$transaction->addTransaction($iAccountId, $config['block_bonus'], 'Bonus', $aBlock['id'])) {
|
||||
$log->logError('Failed to create Bonus transaction in database for user ' . $user->getUserName($iAccountId) . ' for block ' . $aBlock['height']);
|
||||
// Fetch this blocks upstream ID
|
||||
$aBlockRPCInfo = $bitcoin->query('getblock', $aBlock['blockhash']);
|
||||
if ($share->findUpstreamShare($aBlockRPCInfo, $iPreviousShareId)) {
|
||||
$iCurrentUpstreamId = $share->getUpstreamShareId();
|
||||
// Out of order share detection
|
||||
if ($iCurrentUpstreamId < $iPreviousShareId) {
|
||||
// Fetch our offending block
|
||||
$aBlockError = $block->getBlockByShareId($iPreviousShareId);
|
||||
$log->logError('E0001: The block with height ' . $aBlock['height'] . ' found share ' . $iCurrentUpstreamId . ' which is < than ' . $iPreviousShareId . ' of block ' . $aBlockError['height'] . '.');
|
||||
if ( !$aShareError = $share->getShareById($aBlockError['share_id']) || !$aShareCurrent = $share->getShareById($iCurrentUpstreamId)) {
|
||||
// We were not able to fetch all shares that were causing this detection to trigger, bail out
|
||||
$log->logFatal('E0002: Failed to fetch both offending shares ' . $iCurrentUpstreamId . ' and ' . $iPreviousShareId . '. Block height: ' . $aBlock['height']);
|
||||
$monitoring->setStatus($cron_name . "_active", "yesno", 0);
|
||||
$monitoring->setStatus($cron_name . "_message", "message", "E0002: Upstream shares not found");
|
||||
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
|
||||
exit(1);
|
||||
}
|
||||
// Shares seem to be out of order, so lets change them
|
||||
if ( !$share->updateShareById($iCurrentUpstreamId, $aShareError) || !$share->updateShareById($iPreviousShareId, $aShareCurrent)) {
|
||||
// We couldn't update one of the shares! That might mean they have been deleted already
|
||||
$log->logFatal('E0003: Failed to change shares order!');
|
||||
$monitoring->setStatus($cron_name . "_active", "yesno", 0);
|
||||
$monitoring->setStatus($cron_name . "_message", "message", "E0003: Failed share update");
|
||||
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
|
||||
exit(1);
|
||||
}
|
||||
// Reset our offending block so the next run re-checks the shares
|
||||
if (!$block->setShareId($aBlockError['id'], NULL) && !$block->setFinder($aBlockError['id'], NULL) || !$block->setShares($aBlockError['id'], NULL)) {
|
||||
$log->logFatal('E0004: Failed to reset previous block: ' . $aBlockError['height']);
|
||||
$log->logError('Failed to reset block in database: ' . $aBlockError['height']);
|
||||
$monitoring->setStatus($cron_name . "_active", "yesno", 0);
|
||||
$monitoring->setStatus($cron_name . "_message", "message", "E0004: Failed to reset block");
|
||||
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
|
||||
exit(1);
|
||||
}
|
||||
$monitoring->setStatus($cron_name . "_active", "yesno", 0);
|
||||
$monitoring->setStatus($cron_name . "_message", "message", "Out of Order Share detected, autofixed");
|
||||
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
|
||||
exit(0);
|
||||
} else {
|
||||
$iRoundShares = $share->getRoundShares($iPreviousShareId, $iCurrentUpstreamId);
|
||||
$iAccountId = $user->getUserId($share->getUpstreamFinder());
|
||||
}
|
||||
} else {
|
||||
$log->logFatal('E0005: Unable to fetch blocks upstream share, aborted:' . $share->getError());
|
||||
$monitoring->setStatus($cron_name . "_active", "yesno", 0);
|
||||
$monitoring->setStatus($cron_name . "_message", "message", "Unable to fetch blocks " . $aBlock['height'] . " upstream share: " . $share->getError());
|
||||
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$log->logInfo(
|
||||
@ -122,6 +149,17 @@ if (empty($aAllBlocks)) {
|
||||
. $share->share_type
|
||||
);
|
||||
|
||||
// Store new information
|
||||
if (!$block->setShareId($aBlock['id'], $iCurrentUpstreamId))
|
||||
$log->logError('Failed to update share ID in database for block ' . $aBlock['height']);
|
||||
if (!$block->setFinder($aBlock['id'], $iAccountId))
|
||||
$log->logError('Failed to update finder account ID in database for block ' . $aBlock['height']);
|
||||
if (!$block->setShares($aBlock['id'], $iRoundShares))
|
||||
$log->logError('Failed to update share count in database for block ' . $aBlock['height']);
|
||||
if ($config['block_bonus'] > 0 && !$transaction->addTransaction($iAccountId, $config['block_bonus'], 'Bonus', $aBlock['id'])) {
|
||||
$log->logError('Failed to create Bonus transaction in database for user ' . $user->getUserName($iAccountId) . ' for block ' . $aBlock['height']);
|
||||
}
|
||||
|
||||
if ($setting->getValue('disable_notifications') != 1) {
|
||||
// Notify users
|
||||
$aAccounts = $notification->getNotificationAccountIdByType('new_block');
|
||||
|
||||
@ -68,7 +68,7 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
|
||||
$config['reward_type'] == 'block' ? $dReward = $aBlock['amount'] : $dReward = $config['reward'];
|
||||
$aRoundAccountShares = $share->getSharesForAccounts($iPreviousShareId, $aBlock['share_id']);
|
||||
|
||||
$log->logInfo('Shares: ' . $iRoundShares . "\t" . 'Height: ' . $aBlock['height'] . ' Amount: ' . $aBlock['amount'] . "\t" . 'Found by ID: ' . $aBlock['account_id']);
|
||||
$log->logInfo('Target: ' . $pplns_target . '; Shares: ' . $iRoundShares . '; Height: ' . $aBlock['height'] . '; Amount: ' . $aBlock['amount'] . '; Found by ID: ' . $aBlock['account_id']);
|
||||
|
||||
if ($iRoundShares >= $pplns_target) {
|
||||
$log->logDebug("Matching or exceeding PPLNS target of $pplns_target with $iRoundShares");
|
||||
|
||||
@ -54,19 +54,17 @@ if ($config['pps']['reward']['type'] == 'blockavg' && $block->getBlockCount() >
|
||||
if ($config['pps']['reward']['type'] == 'block') {
|
||||
if ($aLastBlock = $block->getLast()) {
|
||||
$pps_reward = $aLastBlock['amount'];
|
||||
$log->logInfo("PPS reward using last block, amount: " . $pps_reward . "\tdifficulty: " . $dDifficulty);
|
||||
} else {
|
||||
$pps_reward = $config['pps']['reward']['default'];
|
||||
$log->logInfo("PPS reward using default, amount: " . $pps_reward . "\tdifficulty: " . $dDifficulty);
|
||||
}
|
||||
} else {
|
||||
$pps_reward = $config['pps']['reward']['default'];
|
||||
$log->logInfo("PPS reward fixed default, amount: " . $pps_reward . "\tdifficulty: " . $dDifficulty);
|
||||
}
|
||||
}
|
||||
|
||||
// Per-share value to be paid out to users
|
||||
$pps_value = round($pps_reward / (pow(2,32) * $dDifficulty) * pow(2, $config['pps_target']), 12);
|
||||
$pps_value = round($pps_reward / (pow(2, $config['target_bits']) * $dDifficulty), 12);
|
||||
|
||||
|
||||
// Find our last share accounted and last inserted share for PPS calculations
|
||||
$iPreviousShareId = $setting->getValue('pps_last_share_id');
|
||||
@ -75,11 +73,16 @@ $iLastShareId = $share->getLastInsertedShareId();
|
||||
// Check for all new shares, we start one higher as our last accounted share to avoid duplicates
|
||||
$aAccountShares = $share->getSharesForAccounts($iPreviousShareId + 1, $iLastShareId);
|
||||
|
||||
$log->logInfo("ID\tUsername\tInvalid\tValid\t\tPPS Value\t\tPayout\t\tDonation\tFee");
|
||||
if (!empty($aAccountShares)) {
|
||||
// Info for this payout
|
||||
$log->logInfo("PPS reward type: " . $config['pps']['reward']['type'] . ", amount: " . $pps_reward . "\tdifficulty: " . $dDifficulty . "\tPPS value: " . $pps_value);
|
||||
$log->logInfo("ID\tUsername\tInvalid\tValid\t\tPPS Value\t\tPayout\t\tDonation\tFee");
|
||||
}
|
||||
|
||||
foreach ($aAccountShares as $aData) {
|
||||
// Take our valid shares and multiply by per share value
|
||||
$aData['payout'] = round($aData['valid'] * $pps_value, 8);
|
||||
// MPOS uses a base difficulty setting to avoid showing weightened shares
|
||||
// Since we need weightened shares here, we go back to the proper value for payouts
|
||||
$aData['payout'] = round($aData['valid'] * pow(2, ($config['difficulty'] - 16)) * $pps_value, 8);
|
||||
|
||||
// Defaults
|
||||
$aData['fee' ] = 0;
|
||||
@ -94,7 +97,7 @@ foreach ($aAccountShares as $aData) {
|
||||
$log->logInfo($aData['id'] . "\t" .
|
||||
$aData['username'] . "\t" .
|
||||
$aData['invalid'] . "\t" .
|
||||
$aData['valid'] . "\t*\t" .
|
||||
$aData['valid'] * pow(2, ($config['difficulty'] - 16)) . "\t*\t" .
|
||||
number_format($pps_value, 12) . "\t=\t" .
|
||||
number_format($aData['payout'], 8) . "\t" .
|
||||
number_format($aData['donation'], 8) . "\t" .
|
||||
|
||||
@ -1,5 +1,11 @@
|
||||
<?php
|
||||
// SHA/Scrypt check
|
||||
|
||||
if (empty($config['algorithm']) || $config['algorithm'] == 'scrypt') {
|
||||
$config['target_bits'] = 16;
|
||||
} else {
|
||||
$config['target_bits'] = 32;
|
||||
}
|
||||
// Default classes
|
||||
require_once(CLASS_DIR . '/debug.class.php');
|
||||
require_once(INCLUDE_DIR . '/lib/KLogger.php');
|
||||
|
||||
@ -8,8 +8,12 @@ if (!defined('SECURITY'))
|
||||
// some cross-class functions.
|
||||
class Base {
|
||||
private $sError = '';
|
||||
protected $table = '';
|
||||
private $values = array(), $types = '';
|
||||
|
||||
public function getTableName() {
|
||||
return $this->table;
|
||||
}
|
||||
public function setDebug($debug) {
|
||||
$this->debug = $debug;
|
||||
}
|
||||
@ -50,6 +54,13 @@ class Base {
|
||||
return $this->sError;
|
||||
}
|
||||
|
||||
protected function getAllAssoc($value, $field='id', $type='i') {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
$stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE $field = ? LIMIT 1");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param($type, $value) && $stmt->execute() && $result = $stmt->get_result())
|
||||
return $result->fetch_assoc();
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Get a single row from the table
|
||||
* @param value string Value to search for
|
||||
|
||||
@ -56,6 +56,30 @@ class Block {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific block, by share_id
|
||||
* @param share_id int Blocks share_id
|
||||
* @return data array Block information from DB
|
||||
**/
|
||||
public function getBlockByShareId($share_id) {
|
||||
$stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE share_id = ? LIMIT 1");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $share_id) && $stmt->execute() && $result = $stmt->get_result())
|
||||
return $result->fetch_assoc();
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific block, by id
|
||||
* @param share_id int Blocks share_id
|
||||
* @return data array Block information from DB
|
||||
**/
|
||||
public function getBlockById($id) {
|
||||
$stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE id = ? LIMIT 1");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $id) && $stmt->execute() && $result = $stmt->get_result())
|
||||
return $result->fetch_assoc();
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get our last, highest share ID inserted for a block
|
||||
* @param none
|
||||
|
||||
@ -225,6 +225,97 @@ class RoundStats {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ALL last blocks from height for admin panel
|
||||
**/
|
||||
public function getAllReportBlocksFoundHeight($iHeight=0, $limit=10) {
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
height, shares
|
||||
FROM $this->tableBlocks
|
||||
WHERE height <= ?
|
||||
ORDER BY height DESC LIMIT ?");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param("ii", $iHeight, $limit) && $stmt->execute() && $result = $stmt->get_result())
|
||||
return $result->fetch_all(MYSQLI_ASSOC);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get USER last blocks from height for admin panel
|
||||
**/
|
||||
public function getUserReportBlocksFoundHeight($iHeight=0, $limit=10, $iUser) {
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
b.height, b.shares
|
||||
FROM $this->tableBlocks AS b
|
||||
LEFT JOIN $this->tableStats AS s ON s.block_id = b.id
|
||||
LEFT JOIN $this->tableUsers AS a ON a.id = s.account_id
|
||||
WHERE b.height <= ? AND a.id = ?
|
||||
ORDER BY height DESC LIMIT ?");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('iii', $iHeight, $iUser, $limit) && $stmt->execute() && $result = $stmt->get_result())
|
||||
return $result->fetch_all(MYSQLI_ASSOC);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get shares for block height for user admin panel
|
||||
**/
|
||||
public function getRoundStatsForUser($iHeight=0, $iUser) {
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
s.valid,
|
||||
s.invalid,
|
||||
s.pplns_valid,
|
||||
s.pplns_invalid
|
||||
FROM $this->tableStats AS s
|
||||
LEFT JOIN $this->tableBlocks AS b ON s.block_id = b.id
|
||||
LEFT JOIN $this->tableUsers AS a ON a.id = s.account_id
|
||||
WHERE b.height = ? AND a.id = ?");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $iHeight, $iUser) && $stmt->execute() && $result = $stmt->get_result())
|
||||
return $result->fetch_assoc();
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get credit transactions for round block height for admin panel
|
||||
**/
|
||||
public function getUserRoundTransHeight($iHeight=0, $iUser) {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
IFNULL(t.amount, 0) AS amount
|
||||
FROM $this->tableTrans AS t
|
||||
LEFT JOIN $this->tableBlocks AS b ON t.block_id = b.id
|
||||
LEFT JOIN $this->tableUsers AS a ON t.account_id = a.id
|
||||
WHERE b.height = ? AND t.type = 'Credit' AND t.account_id = ?");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $iHeight, $iUser) && $stmt->execute() && $result = $stmt->get_result())
|
||||
return $result->fetch_object()->amount;
|
||||
$this->debug->append('Unable to fetch transactions');
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all users for admin panel
|
||||
**/
|
||||
public function getAllUsers($filter='%') {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
a.id AS id,
|
||||
a.username AS username
|
||||
FROM $this->tableUsers AS a
|
||||
WHERE a.username LIKE ?
|
||||
GROUP BY username
|
||||
ORDER BY username");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('s', $filter) && $stmt->execute() && $result = $stmt->get_result()) {
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$aData[$row['id']] = $row['username'];
|
||||
}
|
||||
return $aData;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function checkStmt($bState) {
|
||||
if ($bState ===! true) {
|
||||
$this->debug->append("Failed to prepare statement: " . $this->mysqli->error);
|
||||
|
||||
@ -4,9 +4,8 @@
|
||||
if (!defined('SECURITY'))
|
||||
die('Hacking attempt');
|
||||
|
||||
class Share {
|
||||
private $sError = '';
|
||||
private $table = 'shares';
|
||||
class Share Extends Base {
|
||||
protected $table = 'shares';
|
||||
private $tableArchive = 'shares_archive';
|
||||
private $oUpstream;
|
||||
private $iLastUpstreamId;
|
||||
@ -22,14 +21,6 @@ class Share {
|
||||
$this->debug->append("Instantiated Share class", 2);
|
||||
}
|
||||
|
||||
// get and set methods
|
||||
private function setErrorMessage($msg) {
|
||||
$this->sError = $msg;
|
||||
}
|
||||
public function getError() {
|
||||
return $this->sError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch archive tables name for this class
|
||||
* @param none
|
||||
@ -38,13 +29,43 @@ class Share {
|
||||
public function getArchiveTableName() {
|
||||
return $this->tableArchive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch normal table name for this class
|
||||
* @param none
|
||||
* @return data string Table name
|
||||
* Fetch a single share by ID
|
||||
* @param id int Share ID
|
||||
* @return array Share data
|
||||
**/
|
||||
public function getTableName() {
|
||||
return $this->table;
|
||||
public function getShareById($id) {
|
||||
return $this->getAllAssoc($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an entire shares data
|
||||
**/
|
||||
public function updateShareById($id, $data) {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
$sql = "UPDATE $this->table SET";
|
||||
$start = true;
|
||||
// Remove ID column
|
||||
unset($data['id']);
|
||||
foreach ($data as $column => $value) {
|
||||
$start == true ? $sql .= " $column = ? " : $sql .= ", $column = ?";
|
||||
$start = false;
|
||||
switch($column) {
|
||||
case 'difficulty':
|
||||
$this->addParam('d', $value);
|
||||
break;
|
||||
default:
|
||||
$this->addParam('s', $value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$sql .= " WHERE id = ? LIMIT 1";
|
||||
$this->addParam('i', $id);
|
||||
$stmt = $this->mysqli->prepare($sql);
|
||||
if ($this->checkStmt($stmt) && call_user_func_array( array($stmt, 'bind_param'), $this->getParam()) && $stmt->execute())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -229,7 +250,7 @@ class Share {
|
||||
public function getUpstreamFinder() {
|
||||
return @$this->oUpstream->account;
|
||||
}
|
||||
public function getUpstreamId() {
|
||||
public function getUpstreamShareId() {
|
||||
return @$this->oUpstream->id;
|
||||
}
|
||||
/**
|
||||
@ -240,7 +261,7 @@ class Share {
|
||||
* @param last int Skips all shares up to last to find new share
|
||||
* @return bool
|
||||
**/
|
||||
public function setUpstream($aBlock, $last=0) {
|
||||
public function findUpstreamShare($aBlock, $last=0) {
|
||||
// Many use stratum, so we create our stratum check first
|
||||
$version = pack("I*", sprintf('%08d', $aBlock['version']));
|
||||
$previousblockhash = pack("H*", swapEndian($aBlock['previousblockhash']));
|
||||
@ -343,10 +364,12 @@ class Share {
|
||||
* Fetch the lowest needed share ID from archive
|
||||
**/
|
||||
function getMinArchiveShareId($iCount) {
|
||||
// We don't use baseline here to be more accurate
|
||||
$iCount = $iCount * pow(2, ($this->config['difficulty'] - 16));
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT MIN(b.share_id) AS share_id FROM
|
||||
(
|
||||
SELECT share_id, @total := @total + (IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty) / POW(2, (" . $this->config['difficulty'] . " - 16))) AS total
|
||||
SELECT share_id, @total := @total + IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty) AS total
|
||||
FROM $this->tableArchive, (SELECT @total := 0) AS a
|
||||
WHERE our_result = 'Y'
|
||||
AND @total < ?
|
||||
@ -356,20 +379,13 @@ class Share {
|
||||
");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $iCount, $iCount) && $stmt->execute() && $result = $stmt->get_result())
|
||||
return $result->fetch_object()->share_id;
|
||||
$this->setErrorMessage("Failed fetching additional shares from archive: " . $this->mysqli->error);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function
|
||||
**/
|
||||
private function checkStmt($bState) {
|
||||
if ($bState ===! true) {
|
||||
$this->debug->append("Failed to prepare statement: " . $this->mysqli->error);
|
||||
$this->setErrorMessage('Internal application Error');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
$share = new Share($debug, $mysqli, $user, $block, $config);
|
||||
$share->setMysql($mysqli);
|
||||
$share->setConfig($config);
|
||||
$share->setUser($user);
|
||||
$share->setBlock($block);
|
||||
|
||||
@ -65,7 +65,7 @@ class Statistics {
|
||||
b.*,
|
||||
a.username AS finder,
|
||||
a.is_anonymous AS is_anonymous,
|
||||
ROUND((difficulty * 65535) / POW(2, (" . $this->config['difficulty'] . " -16)), 0) AS estshares
|
||||
ROUND((difficulty * POW(2, 32 - " . $this->config['target_bits'] . ")) / POW(2, (" . $this->config['difficulty'] . " -16)), 0) AS estshares
|
||||
FROM " . $this->block->getTableName() . " AS b
|
||||
LEFT JOIN " . $this->user->getTableName() . " AS a
|
||||
ON b.account_id = a.id
|
||||
@ -90,7 +90,7 @@ class Statistics {
|
||||
b.*,
|
||||
a.username AS finder,
|
||||
a.is_anonymous AS is_anonymous,
|
||||
ROUND((difficulty * 65535) / POW(2, (" . $this->config['difficulty'] . " -16)), 0) AS estshares
|
||||
ROUND((difficulty * POW(2, 32 - " . $this->config['target_bits'] . ")) / POW(2, (" . $this->config['difficulty'] . " -16)), 0) AS estshares
|
||||
FROM " . $this->block->getTableName() . " AS b
|
||||
LEFT JOIN " . $this->user->getTableName() . " AS a
|
||||
ON b.account_id = a.id
|
||||
@ -170,11 +170,11 @@ class Statistics {
|
||||
SELECT
|
||||
(
|
||||
(
|
||||
SELECT IFNULL(ROUND(SUM(IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * 65536 / ? / 1000), 0) AS hashrate
|
||||
SELECT IFNULL(ROUND(SUM(IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * POW(2, " . $this->config['target_bits'] . ") / ? / 1000), 0) AS hashrate
|
||||
FROM " . $this->share->getTableName() . "
|
||||
WHERE time > DATE_SUB(now(), INTERVAL ? SECOND)
|
||||
) + (
|
||||
SELECT IFNULL(ROUND(SUM(IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * 65536 / ? / 1000), 0) AS hashrate
|
||||
SELECT IFNULL(ROUND(SUM(IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * POW(2, " . $this->config['target_bits'] . ") / ? / 1000), 0) AS hashrate
|
||||
FROM " . $this->share->getArchiveTableName() . "
|
||||
WHERE time > DATE_SUB(now(), INTERVAL ? SECOND)
|
||||
)
|
||||
@ -370,14 +370,14 @@ class Statistics {
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
(
|
||||
SELECT IFNULL(ROUND(SUM(IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * 65536 / ? / 1000), 0) AS hashrate
|
||||
SELECT IFNULL(ROUND(SUM(IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * POW(2, " . $this->config['target_bits'] . ") / ? / 1000), 0) AS hashrate
|
||||
FROM " . $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 ? SECOND)
|
||||
AND u.id = ?
|
||||
) + (
|
||||
SELECT IFNULL(ROUND(SUM(IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * 65536 / ? / 1000), 0) AS hashrate
|
||||
SELECT IFNULL(ROUND(SUM(IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * POW(2, " . $this->config['target_bits'] . ") / ? / 1000), 0) AS hashrate
|
||||
FROM " . $this->share->getArchiveTableName() . " AS s,
|
||||
" . $this->user->getTableName() . " AS u
|
||||
WHERE u.username = SUBSTRING_INDEX( s.username, '.', 1 )
|
||||
@ -392,7 +392,29 @@ class Statistics {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getUserUnpaidPPSShares($account_id, $last_paid_pps_id) {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
if ($this->getGetCache() && $data = $this->memcache->get(__FUNCTION__ . $account_id)) return $data;
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
ROUND(IFNULL(SUM(IF(s.difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)), 0) / POW(2, (" . $this->config['difficulty'] . " - 16)), 0) AS total
|
||||
FROM " . $this->share->getTableName() . " AS s
|
||||
JOIN " . $this->user->getTableName() . " AS a
|
||||
ON a.username = SUBSTRING_INDEX( s.username, '.', 1 )
|
||||
AND a.id = ?
|
||||
AND s.id > ?");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param("ii", $account_id, $last_paid_pps_id) && $stmt->execute() && $result = $stmt->get_result() )
|
||||
return $this->memcache->setCache(__FUNCTION__ . $account_id, $result->fetch_object()->total);
|
||||
$this->debug->append("Failed fetching average share dificulty: " . $this->mysqli->error, 3);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get average share difficulty across all workers for user
|
||||
* @param account_id int Account ID
|
||||
* @param interval int Data interval in seconds
|
||||
* @return double Share difficulty or 0
|
||||
**/
|
||||
public function getUserShareDifficulty($account_id, $interval=600) {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
if ($this->getGetCache() && $data = $this->memcache->get(__FUNCTION__ . $account_id)) return $data;
|
||||
@ -454,7 +476,7 @@ class Statistics {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
if ($data = $this->memcache->get(__FUNCTION__ . $worker_id)) return $data;
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT IFNULL(ROUND(SUM(IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * 65536 / 600 / 1000), 0) AS hashrate
|
||||
SELECT IFNULL(ROUND(SUM(IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * POW(2, " . $this->config['target_bits'] . ") / 600 / 1000), 0) AS hashrate
|
||||
FROM " . $this->share->getTableName() . " AS s,
|
||||
" . $this->user->getTableName() . " AS u
|
||||
WHERE u.username = SUBSTRING_INDEX( s.username, '.', 1 )
|
||||
@ -524,7 +546,7 @@ class Statistics {
|
||||
a.username AS account,
|
||||
a.donate_percent AS donate_percent,
|
||||
a.is_anonymous AS is_anonymous,
|
||||
IFNULL(ROUND(SUM(t1.difficulty) * 65536 / 600 / 1000, 2), 0) AS hashrate
|
||||
IFNULL(ROUND(SUM(t1.difficulty) * POW(2, " . $this->config['target_bits'] . ") / 600 / 1000, 2), 0) AS hashrate
|
||||
FROM
|
||||
(
|
||||
SELECT IFNULL(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty), 0) AS difficulty, username FROM " . $this->share->getTableName() . " WHERE time > DATE_SUB(now(), INTERVAL 10 MINUTE) AND our_result = 'Y'
|
||||
@ -553,7 +575,7 @@ class Statistics {
|
||||
if ($data = $this->memcache->get(__FUNCTION__ . $account_id)) return $data;
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
IFNULL(ROUND(SUM(IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)) * 65536/3600/1000), 0) AS hashrate,
|
||||
IFNULL(ROUND(SUM(IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)) * POW(2, " . $this->config['target_bits'] . ") / 3600 / 1000), 0) AS hashrate,
|
||||
HOUR(s.time) AS hour
|
||||
FROM " . $this->share->getTableName() . " AS s, accounts AS a
|
||||
WHERE time < NOW() - INTERVAL 1 HOUR
|
||||
@ -563,7 +585,7 @@ class Statistics {
|
||||
GROUP BY HOUR(time)
|
||||
UNION ALL
|
||||
SELECT
|
||||
IFNULL(ROUND(SUM(IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)) * 65536/3600/1000), 0) AS hashrate,
|
||||
IFNULL(ROUND(SUM(IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)) * POW(2, " . $this->config['target_bits'] . ") / 3600 / 1000), 0) AS hashrate,
|
||||
HOUR(s.time) AS hour
|
||||
FROM " . $this->share->getArchiveTableName() . " AS s, accounts AS a
|
||||
WHERE time < NOW() - INTERVAL 1 HOUR
|
||||
@ -594,7 +616,7 @@ class Statistics {
|
||||
if ($this->getGetCache() && $data = $this->memcache->get(__FUNCTION__)) return $data;
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
IFNULL(ROUND(SUM(IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)) * 65536/3600/1000), 0) AS hashrate,
|
||||
IFNULL(ROUND(SUM(IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)) * POW(2, " . $this->config['target_bits'] . ") / 3600 / 1000), 0) AS hashrate,
|
||||
HOUR(s.time) AS hour
|
||||
FROM " . $this->share->getTableName() . " AS s
|
||||
WHERE time < NOW() - INTERVAL 1 HOUR
|
||||
@ -602,7 +624,7 @@ class Statistics {
|
||||
GROUP BY HOUR(time)
|
||||
UNION ALL
|
||||
SELECT
|
||||
IFNULL(ROUND(SUM(IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)) * 65536/3600/1000), 0) AS hashrate,
|
||||
IFNULL(ROUND(SUM(IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)) * POW(2, " . $this->config['target_bits'] . ") / 3600 / 1000), 0) AS hashrate,
|
||||
HOUR(s.time) AS hour
|
||||
FROM " . $this->share->getArchiveTableName() . " AS s
|
||||
WHERE time < NOW() - INTERVAL 1 HOUR
|
||||
@ -645,18 +667,16 @@ class Statistics {
|
||||
}
|
||||
} else {
|
||||
// Hack so we can use this method for PPS estimates too
|
||||
// value1 = shares/s
|
||||
// value2 = avg share difficulty
|
||||
if (@$value1 > 0 && @$value2 > 0) {
|
||||
// Default: No fees applied so multiply by 1
|
||||
$fee = 1;
|
||||
if ($this->config['fees'] > 0)
|
||||
$bNoFees == 0 ? $fee = round(((float)$this->config['fees'] / 100), 8) : $fee = 1;
|
||||
$hour = 60 * 60;
|
||||
$pps = $value1 * $value2 * $ppsvalue;
|
||||
$hour = 3600;
|
||||
$aEstimates['hours1'] = $pps * $hour * $fee;
|
||||
$aEstimates['hours1'] = $pps * $hour;
|
||||
$aEstimates['hours24'] = $pps * 24 * $hour;
|
||||
$aEstimates['days7'] = $pps * 24 * 7 * $hour;
|
||||
$aEstimates['days14'] = $pps * 14 * 24 * 7 * $hour;
|
||||
$aEstimates['days30'] = $pps * 30 * 24 * 7 * $hour;
|
||||
$aEstimates['days14'] = $pps * 14 * 24 * $hour;
|
||||
$aEstimates['days30'] = $pps * 30 * 24 * $hour;
|
||||
} else {
|
||||
$aEstimates['hours1'] = 0;
|
||||
$aEstimates['hours24'] = 0;
|
||||
|
||||
@ -5,7 +5,8 @@ if (!defined('SECURITY'))
|
||||
die('Hacking attempt');
|
||||
|
||||
class Transaction extends Base {
|
||||
private $sError = '', $table = 'transactions';
|
||||
private $sError = '';
|
||||
protected $table = 'transactions';
|
||||
public $num_rows = 0, $insert_id = 0;
|
||||
|
||||
/**
|
||||
|
||||
@ -176,6 +176,40 @@ class Worker {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all workers for admin panel
|
||||
* @param limit int
|
||||
* @return mixed array Workers and their settings or false
|
||||
**/
|
||||
public function getAllWorkers($iLimit=0) {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT id, username, password, monitor, difficulty,
|
||||
(
|
||||
SELECT
|
||||
IFNULL(IF(our_result='Y', ROUND(SUM(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * 65536 / 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(SUM(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * 65536 / 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
|
||||
ORDER BY hashrate DESC LIMIT ?");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $iLimit) && $stmt->execute() && $result = $stmt->get_result())
|
||||
return $result->fetch_all(MYSQLI_ASSOC);
|
||||
// Catchall
|
||||
$this->setErrorMessage('Failed to fetch workers');
|
||||
$this->debug->append('Fetching workers failed: ' . $this->mysqli->error);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all currently active workers in the past 10 minutes
|
||||
* @param none
|
||||
|
||||
@ -20,6 +20,17 @@ define('DEBUG', 0);
|
||||
// SALT used to hash passwords
|
||||
define('SALT', 'PLEASEMAKEMESOMETHINGRANDOM');
|
||||
|
||||
/**
|
||||
* Underlying coin algorithm that you are mining on. Set this to whatever your coin needs:
|
||||
*
|
||||
* Options:
|
||||
* sha256d : SHA coins like Bitcoin
|
||||
* scrypt : Scrypt based coins like Litecoin
|
||||
* Default:
|
||||
* scrypt : Scrypt is default
|
||||
**/
|
||||
$config['algorithm'] = 'scrypt';
|
||||
|
||||
/**
|
||||
* Database configuration
|
||||
*
|
||||
@ -308,10 +319,6 @@ $config['pps']['reward']['default'] = 50;
|
||||
$config['pps']['reward']['type'] = 'blockavg';
|
||||
$config['pps']['blockavg']['blockcount'] = 10;
|
||||
|
||||
// pps base payout target, default 16 = difficulty 1 shares for vardiff
|
||||
// (1/(65536 * difficulty) * reward) = (reward / (pow(2,32) * difficulty) * pow(2, 16))
|
||||
$config['pps_target'] = 16; // do not change unless you know what it does
|
||||
|
||||
/**
|
||||
* Memcache configuration
|
||||
*
|
||||
|
||||
18
public/include/pages/admin/poolworkers.inc.php
Normal file
18
public/include/pages/admin/poolworkers.inc.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
// Make sure we are called from index.php
|
||||
if (!defined('SECURITY')) die('Hacking attempt');
|
||||
|
||||
// Check user to ensure they are admin
|
||||
if (!$user->isAuthenticated() || !$user->isAdmin($_SESSION['USERDATA']['id'])) {
|
||||
header("HTTP/1.1 404 Page not found");
|
||||
die("404 Page not found");
|
||||
}
|
||||
|
||||
$iActiveWorkers = $worker->getCountAllActiveWorkers();
|
||||
$aWorkers = $worker->getAllWorkers($iActiveWorkers);
|
||||
|
||||
$smarty->assign('WORKERS', $aWorkers);
|
||||
|
||||
$smarty->assign('CONTENT', 'default.tpl');
|
||||
|
||||
?>
|
||||
86
public/include/pages/admin/reports.inc.php
Normal file
86
public/include/pages/admin/reports.inc.php
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
// Make sure we are called from index.php
|
||||
if (!defined('SECURITY')) die('Hacking attempt');
|
||||
|
||||
// Check user to ensure they are admin
|
||||
if (!$user->isAuthenticated() || !$user->isAdmin($_SESSION['USERDATA']['id'])) {
|
||||
header("HTTP/1.1 404 Page not found");
|
||||
die("404 Page not found");
|
||||
}
|
||||
|
||||
if (!$smarty->isCached('master.tpl', $smarty_cache_key)) {
|
||||
$debug->append('No cached version available, fetching from backend', 3);
|
||||
|
||||
$aUserList = $roundstats->getAllUsers('%');
|
||||
|
||||
$iHeight = 0;
|
||||
$iUserId = 0;
|
||||
$filter = 0;
|
||||
$userName = 'None';
|
||||
if (@$_REQUEST['id']) {
|
||||
$iUserId = $_REQUEST['id'];
|
||||
$userName = $user->getUserName($_REQUEST['id']);
|
||||
}
|
||||
|
||||
$setting->getValue('statistics_block_count') ? $iLimit = $setting->getValue('statistics_block_count') : $iLimit = 20;
|
||||
if (@$_REQUEST['limit']) {
|
||||
$iLimit = $_REQUEST['limit'];
|
||||
if ( $iLimit > 1000 )
|
||||
$iLimit = 1000;
|
||||
}
|
||||
|
||||
if (@$_REQUEST['next'] && !empty($_REQUEST['height'])) {
|
||||
$iHeight = @$roundstats->getNextBlockForStats($_REQUEST['height'], $iLimit);
|
||||
if (!$iHeight) {
|
||||
$aBlock = $block->getLast();
|
||||
$iHeight = $aBlock['height'];
|
||||
}
|
||||
} else if (@$_REQUEST['prev'] && !empty($_REQUEST['height'])) {
|
||||
$iHeight = $_REQUEST['height'];
|
||||
} else if (!empty($_REQUEST['height']) && is_numeric($_REQUEST['height'])) {
|
||||
$iHeight = $_REQUEST['height'];
|
||||
} else {
|
||||
$aBlock = $block->getLast();
|
||||
$iHeight = $aBlock['height'];
|
||||
}
|
||||
|
||||
if (@$_REQUEST['search']) {
|
||||
$iHeight = $roundstats->searchForBlockHeight($_REQUEST['search']);
|
||||
}
|
||||
|
||||
if (@$_REQUEST['filter']) {
|
||||
$filter = $_REQUEST['filter'];
|
||||
}
|
||||
|
||||
$aBlocksData = array();
|
||||
if ( $iUserId ) {
|
||||
if ($filter) {
|
||||
$aBlocksData = $roundstats->getAllReportBlocksFoundHeight($iHeight, $iLimit);
|
||||
} else {
|
||||
$aBlocksData = $roundstats->getUserReportBlocksFoundHeight($iHeight, $iLimit, $iUserId);
|
||||
}
|
||||
foreach($aBlocksData as $key => $aData) {
|
||||
$aBlocksData[$key]['pplns_shares'] = @$roundstats->getPPLNSRoundShares($aData['height']);
|
||||
$aBlocksData[$key]['user'] = @$roundstats->getRoundStatsForUser($aData['height'], $iUserId);
|
||||
$aBlocksData[$key]['user_credit'] = @$roundstats->getUserRoundTransHeight($aData['height'], $iUserId);
|
||||
}
|
||||
}
|
||||
|
||||
$smarty->assign('REPORTDATA', $aBlocksData);
|
||||
$smarty->assign("USERLIST", $aUserList);
|
||||
$smarty->assign("USERNAME", $userName);
|
||||
$smarty->assign("USERID", $iUserId);
|
||||
$smarty->assign("BLOCKLIMIT", $iLimit);
|
||||
$smarty->assign("HEIGHT", $iHeight);
|
||||
$smarty->assign("FILTER", $filter);
|
||||
} else {
|
||||
$debug->append('Using cached page', 3);
|
||||
}
|
||||
|
||||
if ($user->isAuthenticated(false)) {
|
||||
$smarty->assign("CONTENT", "default.tpl");
|
||||
} else {
|
||||
$smarty->assign("CONTENT", "empty");
|
||||
}
|
||||
?>
|
||||
@ -41,7 +41,9 @@ $aRoundShares = $statistics->getRoundShares();
|
||||
|
||||
if ($config['payout_system'] != 'pps') {
|
||||
$aEstimates = $statistics->getUserEstimates($aRoundShares, $aUserRoundShares, $user->getUserDonatePercent($user_id), $user->getUserNoFee($user_id));
|
||||
$dUnpaidShares = 0;
|
||||
} else {
|
||||
$dUnpaidShares = $statistics->getUserUnpaidPPSShares($user_id, $setting->getValue('pps_last_share_id'));
|
||||
if ($config['pps']['reward']['type'] == 'blockavg' && $block->getBlockCount() > 0) {
|
||||
$pps_reward = round($block->getAvgBlockReward($config['pps']['blockavg']['blockcount']));
|
||||
} else {
|
||||
@ -56,7 +58,7 @@ if ($config['payout_system'] != 'pps') {
|
||||
}
|
||||
}
|
||||
|
||||
$ppsvalue = round($pps_reward / (pow(2,32) * $dDifficulty) * pow(2, $config['pps_target']), 12);
|
||||
$ppsvalue = round($pps_reward / (pow(2,32) * $dDifficulty) * pow(2, $config['target_bits']), 12);
|
||||
$aEstimates = $statistics->getUserEstimates($dPersonalSharerate, $dPersonalShareDifficulty, $user->getUserDonatePercent($user_id), $user->getUserNoFee($user_id), $ppsvalue);
|
||||
}
|
||||
|
||||
@ -89,7 +91,7 @@ $data = array(
|
||||
'raw' => array( 'personal' => array( 'hashrate' => $dPersonalHashrate ), 'pool' => array( 'hashrate' => $dPoolHashrate ), 'network' => array( 'hashrate' => $dNetworkHashrate / 1000 ) ),
|
||||
'personal' => array (
|
||||
'hashrate' => $dPersonalHashrateAdjusted, 'sharerate' => $dPersonalSharerate, 'sharedifficulty' => $dPersonalShareDifficulty,
|
||||
'shares' => array('valid' => $aUserRoundShares['valid'], 'invalid' => $aUserRoundShares['invalid'], 'invalid_percent' => $dUserInvalidPercent),
|
||||
'shares' => array('valid' => $aUserRoundShares['valid'], 'invalid' => $aUserRoundShares['invalid'], 'invalid_percent' => $dUserInvalidPercent, 'unpaid' => $dUnpaidShares ),
|
||||
'balance' => $transaction->getBalance($user_id), 'estimates' => $aEstimates, 'workers' => $aWorkers ),
|
||||
'pool' => array(
|
||||
'workers' => $worker->getCountAllActiveWorkers(), 'hashrate' => $dPoolHashrateAdjusted,
|
||||
|
||||
@ -140,7 +140,9 @@ if (@$_SESSION['USERDATA']['id']) {
|
||||
}
|
||||
}
|
||||
|
||||
$aGlobal['ppsvalue'] = number_format(round($pps_reward / (pow(2,32) * $dDifficulty) * pow(2, $config['pps_target']), 12) ,12);
|
||||
$aGlobal['userdata']['pps']['unpaidshares'] = $statistics->getUserUnpaidPPSShares($_SESSION['USERDATA']['id'], $setting->getValue('pps_last_share_id'));
|
||||
$aGlobal['ppsvalue'] = number_format(round($pps_reward / (pow(2, $config['target_bits']) * $dDifficulty), 12) ,12);
|
||||
$aGlobal['poolppsvalue'] = $aGlobal['ppsvalue'] * pow(2, $config['difficulty'] - 16);
|
||||
$aGlobal['userdata']['sharedifficulty'] = $statistics->getUserShareDifficulty($_SESSION['USERDATA']['id']);
|
||||
$aGlobal['userdata']['estimates'] = $statistics->getUserEstimates($aGlobal['userdata']['sharerate'], $aGlobal['userdata']['sharedifficulty'], $aGlobal['userdata']['donate_percent'], $aGlobal['userdata']['no_fees'], $aGlobal['ppsvalue']);
|
||||
break;
|
||||
|
||||
34
public/templates/mmcFE/admin/poolworkers/default.tpl
Normal file
34
public/templates/mmcFE/admin/poolworkers/default.tpl
Normal file
@ -0,0 +1,34 @@
|
||||
{include file="global/block_header.tpl" BLOCK_HEADER="{count($WORKERS)} Current Active Pool Workers"}
|
||||
<center>
|
||||
<table border="0" style="font-size:13px;">
|
||||
<thead>
|
||||
<tr style="background-color:#B6DAFF;">
|
||||
<th>Worker Name</th>
|
||||
<th>Password</th>
|
||||
<th class="center">Active</th>
|
||||
{if $GLOBAL.config.disable_notifications != 1}<th class="center">Monitor</th>{/if}
|
||||
<th class="right">Khash/s</th>
|
||||
<th class="right">Difficulty</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{nocache}
|
||||
{section worker $WORKERS}
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{$WORKERS[worker].username|escape}</td>
|
||||
<td>{$WORKERS[worker].password|escape}</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}
|
||||
<td class="center">
|
||||
<img src="{$PATH}/images/{if $WORKERS[worker].monitor}success{else}error{/if}.gif" />
|
||||
</td>
|
||||
{/if}
|
||||
<td class="right">{$WORKERS[worker].hashrate|number_format|default:"0"}</td>
|
||||
<td class="right">{if $WORKERS[worker].hashrate > 0}{$WORKERS[worker].difficulty|number_format:"2"|default:"0"}{else}0{/if}</td>
|
||||
</tr>
|
||||
{/section}
|
||||
{/nocache}
|
||||
</tbody>
|
||||
</table>
|
||||
</center>
|
||||
{include file="global/block_footer.tpl"}
|
||||
2
public/templates/mmcFE/admin/reports/default.tpl
Normal file
2
public/templates/mmcFE/admin/reports/default.tpl
Normal file
@ -0,0 +1,2 @@
|
||||
{include file="admin/reports/earnings_control.tpl"}
|
||||
{include file="admin/reports/earnings_report.tpl"}
|
||||
50
public/templates/mmcFE/admin/reports/earnings_control.tpl
Normal file
50
public/templates/mmcFE/admin/reports/earnings_control.tpl
Normal file
@ -0,0 +1,50 @@
|
||||
{include file="global/block_header.tpl" ALIGN="left" BLOCK_STYLE="width: 100%" BLOCK_HEADER="Earnings Information" STYLE="padding-left:5px;padding-right:5px;"}
|
||||
<form action="{$smarty.server.PHP_SELF}" method="post">
|
||||
<input type="hidden" name="page" value="{$smarty.request.page|escape}">
|
||||
<input type="hidden" name="action" value="{$smarty.request.action|escape}">
|
||||
<table width="100%" border="0" style="font-size:13px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="left">
|
||||
<a href="{$smarty.server.PHP_SELF}?page={$smarty.request.page}&action={$smarty.request.action}&height={if is_array($REPORTDATA) && count($REPORTDATA) > ($BLOCKLIMIT - 1)}{$REPORTDATA[$BLOCKLIMIT - 1].height}{/if}&prev=1&limit={$BLOCKLIMIT}&id={$USERID}&filter={$FILTER}"><img src="{$PATH}/images/prev.png" /></a>
|
||||
</td>
|
||||
<td class="right">
|
||||
<a href="{$smarty.server.PHP_SELF}?page={$smarty.request.page}&action={$smarty.request.action}&height={if is_array($REPORTDATA) && count($REPORTDATA) > 0}{$REPORTDATA[0].height}{/if}&next=1&limit={$BLOCKLIMIT}&id={$USERID}&filter={$FILTER}"><img src="{$PATH}/images/next.png" /></a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table width="100%" border="0" style="font-size:13px;">
|
||||
<thead>
|
||||
<tr style="background-color:#B6DAFF;">
|
||||
<th class="center">Select User</th>
|
||||
<th class="center">Block Limit</th>
|
||||
<th class="center">Starting Block Height</th>
|
||||
<th class="center">Show Empty Rounds</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="center">
|
||||
{html_options name="id" options=$USERLIST selected=$USERID|default:"0"}
|
||||
</td>
|
||||
<td class="center">
|
||||
<input size="12" type="text" name="limit" value="{$BLOCKLIMIT|default:"20"}" />
|
||||
</td>
|
||||
<td class="center">
|
||||
<input size="12" type="text" name="search" value="{$HEIGHT|default:"%"}">
|
||||
</td>
|
||||
<td class="center">
|
||||
<input type="checkbox" name="filter" value="1" id="filter" {if $FILTER}checked{/if} />
|
||||
<label for="filter"></label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="right" colspan="4">
|
||||
<input type="submit" class="submit small" value="Submit">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
{include file="global/block_footer.tpl"}
|
||||
85
public/templates/mmcFE/admin/reports/earnings_report.tpl
Normal file
85
public/templates/mmcFE/admin/reports/earnings_report.tpl
Normal file
@ -0,0 +1,85 @@
|
||||
{include file="global/block_header.tpl" ALIGN="left" BLOCK_STYLE="width: 100%" BLOCK_HEADER="Earnings Report Last {$BLOCKLIMIT} Blocks For User: {$USERNAME}" STYLE="padding-left:5px;padding-right:5px;"}
|
||||
<table class="left" width="100%" class="sortable" style="font-size:12px;">
|
||||
<thead>
|
||||
<tr style="background-color:#B6DAFF;">
|
||||
<th >Block</th>
|
||||
<th class="right">Round Shares</th>
|
||||
<th class="right">Round Valid</th>
|
||||
<th class="right">Invalid</th>
|
||||
<th class="right">Invalid %</th>
|
||||
<th class="right">Round %</th>
|
||||
<th class="right">PPLNS Shares</th>
|
||||
<th class="right">PPLNS Valid</th>
|
||||
<th class="right">Invalid</th>
|
||||
<th class="right">Invalid %</th>
|
||||
<th class="right">PPLNS %</th>
|
||||
<th class="right">Variance</th>
|
||||
<th class="right">Amount</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{assign var=percentage value=0}
|
||||
{assign var=percentage1 value=0}
|
||||
{assign var=percentage2 value=0}
|
||||
{assign var=totalvalid value=0}
|
||||
{assign var=totalinvalid value=0}
|
||||
{assign var=totalshares value=0}
|
||||
{assign var=usertotalshares value=0}
|
||||
{assign var=totalpercentage value=0}
|
||||
{assign var=pplnsshares value=0}
|
||||
{assign var=userpplnsshares value=0}
|
||||
{assign var=pplnsvalid value=0}
|
||||
{assign var=pplnsinvalid value=0}
|
||||
{assign var=amount value=0}
|
||||
{section txs $REPORTDATA}
|
||||
{assign var="totalshares" value=$totalshares+$REPORTDATA[txs].shares}
|
||||
{assign var=totalvalid value=$totalvalid+$REPORTDATA[txs]['user'].valid}
|
||||
{assign var=totalinvalid value=$totalinvalid+$REPORTDATA[txs]['user'].invalid}
|
||||
{assign var="pplnsshares" value=$pplnsshares+$REPORTDATA[txs].pplns_shares}
|
||||
{assign var=pplnsvalid value=$pplnsvalid+$REPORTDATA[txs]['user'].pplns_valid}
|
||||
{assign var=pplnsinvalid value=$pplnsinvalid+$REPORTDATA[txs]['user'].pplns_invalid}
|
||||
{assign var=amount value=$amount+$REPORTDATA[txs].user_credit}
|
||||
{if $REPORTDATA[txs]['user'].pplns_valid > 0}
|
||||
{assign var="userpplnsshares" value=$userpplnsshares+$REPORTDATA[txs].pplns_shares}
|
||||
{/if}
|
||||
{if $REPORTDATA[txs]['user'].valid > 0}
|
||||
{assign var="usertotalshares" value=$usertotalshares+$REPORTDATA[txs].shares}
|
||||
{/if}
|
||||
<tr>
|
||||
<td><a href="{$smarty.server.PHP_SELF}?page=statistics&action=round&height={$REPORTDATA[txs].height}">{$REPORTDATA[txs].height|default:"0"}</a></td>
|
||||
<td class="right">{$REPORTDATA[txs].shares|default:"0"}</td>
|
||||
<td class="right">{$REPORTDATA[txs]['user'].valid|number_format|default:"0"}</td>
|
||||
<td class="right">{$REPORTDATA[txs]['user'].invalid|number_format|default:"0"}</td>
|
||||
<td class="right">{if $REPORTDATA[txs]['user'].invalid > 0 }{($REPORTDATA[txs]['user'].invalid / $REPORTDATA[txs]['user'].valid * 100)|number_format:"2"|default:"0"}{else}0.00{/if}</td>
|
||||
<td class="right">{if $REPORTDATA[txs]['user'].valid > 0 }{(( 100 / $REPORTDATA[txs].shares) * $REPORTDATA[txs]['user'].valid)|number_format:"2"}{else}0.00{/if}</td>
|
||||
<td class="right">{$REPORTDATA[txs].pplns_shares|number_format|default:"0"}</td>
|
||||
<td class="right">{$REPORTDATA[txs]['user'].pplns_valid|number_format|default:"0"}</td>
|
||||
<td class="right">{$REPORTDATA[txs]['user'].pplns_invalid|number_format|default:"0"}</td>
|
||||
<td class="right">{if $REPORTDATA[txs]['user'].pplns_invalid > 0 && $REPORTDATA[txs]['user'].pplns_valid > 0 }{($REPORTDATA[txs]['user'].pplns_invalid / $REPORTDATA[txs]['user'].pplns_valid * 100)|number_format:"2"|default:"0"}{else}0.00{/if}</td>
|
||||
<td class="right">{if $REPORTDATA[txs].shares > 0 && $REPORTDATA[txs]['user'].pplns_valid > 0}{(( 100 / $REPORTDATA[txs].pplns_shares) * $REPORTDATA[txs]['user'].pplns_valid)|number_format:"2"|default:"0"}{else}0.00{/if}</td>
|
||||
<td class="right">{if $REPORTDATA[txs]['user'].valid > 0 && $REPORTDATA[txs]['user'].pplns_valid > 0}{math assign="percentage1" equation=(100 / ((( 100 / $REPORTDATA[txs].shares) * $REPORTDATA[txs]['user'].valid) / (( 100 / $REPORTDATA[txs].pplns_shares) * $REPORTDATA[txs]['user'].pplns_valid)))}{else if $REPORTDATA[txs]['user'].pplns_valid == 0}{assign var=percentage1 value=0}{else}{assign var=percentage1 value=100}{/if}
|
||||
<font color="{if ($percentage1 >= 100)}green{else}red{/if}">{$percentage1|number_format:"2"|default:"0"}</font></b></td>
|
||||
<td class="right">{$REPORTDATA[txs].user_credit|default:"0"|number_format:"8"}</td>
|
||||
{assign var=percentage1 value=0}
|
||||
</tr>
|
||||
{/section}
|
||||
<tr>
|
||||
<td><b>Totals</b></td>
|
||||
<td class="right">{$totalshares|number_format}</td>
|
||||
<td class="right">{$totalvalid|number_format}</td>
|
||||
<td class="right">{$totalinvalid|number_format}</td>
|
||||
<td class="right">{if $totalinvalid > 0 && $totalvalid > 0 }{($totalinvalid / $totalvalid * 100)|number_format:"2"|default:"0"}{else}0.00{/if}</td>
|
||||
<td class="right">{if $usertotalshares > 0 && $totalvalid > 0}{(( 100 / $usertotalshares) * $totalvalid)|number_format:"2"|default:"0"}{else}0.00{/if}</td>
|
||||
<td class="right">{$pplnsshares|number_format}</td>
|
||||
<td class="right">{$pplnsvalid|number_format}</td>
|
||||
<td class="right">{$pplnsinvalid|number_format}</td>
|
||||
<td class="right">{if $pplnsinvalid > 0 && $pplnsvalid > 0 }{($pplnsinvalid / $pplnsvalid * 100)|number_format:"2"|default:"0"}{else}0.00{/if}</td>
|
||||
<td class="right">{if $userpplnsshares > 0 && $pplnsvalid > 0}{(( 100 / $userpplnsshares) * $pplnsvalid)|number_format:"2"|default:"0"}{else}0.00{/if}</td>
|
||||
<td class="right">{if $totalvalid > 0 && $pplnsvalid > 0}{math assign="percentage2" equation=(100 / ((( 100 / $usertotalshares) * $totalvalid) / (( 100 / $userpplnsshares) * $pplnsvalid)))}{else if $pplnsvalid == 0}{assign var=percentage2 value=0}{else}{assign var=percentage2 value=100}{/if}
|
||||
<font color="{if ($percentage2 >= 100)}green{else}red{/if}">{$percentage2|number_format:"2"|default:"0"}</font></b></td>
|
||||
<td class="right">{$amount|default:"0"|number_format:"8"}</td>
|
||||
{assign var=percentage2 value=0}
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{include file="global/block_footer.tpl"}
|
||||
@ -21,6 +21,8 @@
|
||||
<li><a href="{$smarty.server.PHP_SELF}?page=admin&action=transactions">Transactions</a></li>
|
||||
<li><a href="{$smarty.server.PHP_SELF}?page=admin&action=settings">Settings</a></li>
|
||||
<li><a href="{$smarty.server.PHP_SELF}?page=admin&action=news">News</a></li>
|
||||
<li><a href="{$smarty.server.PHP_SELF}?page=admin&action=reports">Reports</a></li>
|
||||
<li><a href="{$smarty.server.PHP_SELF}?page=admin&action=poolworkers">Pool Workers</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
{/if}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<article class="module width_full">
|
||||
<header><h3>ThePool Collective</h3></header>
|
||||
<header><h3>{$GLOBAL.website.name}</h3></header>
|
||||
<div class="module_content">
|
||||
<table width="100%">
|
||||
<tbody>
|
||||
|
||||
31
public/templates/mpos/admin/poolworkers/default.tpl
Normal file
31
public/templates/mpos/admin/poolworkers/default.tpl
Normal file
@ -0,0 +1,31 @@
|
||||
<article class="module width_3_quarter">
|
||||
<header><h3>{count($WORKERS)} Current Active Pool Workers</h3></header>
|
||||
<table class="tablesorter" cellspacing="0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th align="left">Worker Name</th>
|
||||
<th align="left">Password</th>
|
||||
<th align="center">Active</th>
|
||||
{if $GLOBAL.config.disable_notifications != 1}<th align="center">Monitor</th>{/if}
|
||||
<th align="right">Khash/s</th>
|
||||
<th align="right" style="padding-right: 25px;">Difficulty</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{nocache}
|
||||
{section worker $WORKERS}
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="left">{$WORKERS[worker].username|escape}</td>
|
||||
<td align="left">{$WORKERS[worker].password|escape}</td>
|
||||
<td align="center"><i class="icon-{if $WORKERS[worker].hashrate > 0}ok{else}cancel{/if}"></i></td>
|
||||
{if $GLOBAL.config.disable_notifications != 1}
|
||||
<td align="center"><i class="icon-{if $WORKERS[worker].monitor}ok{else}cancel{/if}"></i></td>
|
||||
{/if}
|
||||
<td align="right">{$WORKERS[worker].hashrate|number_format|default:"0"}</td>
|
||||
<td align="right" style="padding-right: 25px;">{if $WORKERS[worker].hashrate > 0}{$WORKERS[worker].difficulty|number_format:"2"|default:"0"}{else}0{/if}</td>
|
||||
</tr>
|
||||
{/section}
|
||||
{/nocache}
|
||||
</tbody>
|
||||
</table>
|
||||
</article>
|
||||
2
public/templates/mpos/admin/reports/default.tpl
Normal file
2
public/templates/mpos/admin/reports/default.tpl
Normal file
@ -0,0 +1,2 @@
|
||||
{include file="admin/reports/earnings_control.tpl"}
|
||||
{include file="admin/reports/earnings_report.tpl"}
|
||||
55
public/templates/mpos/admin/reports/earnings_control.tpl
Normal file
55
public/templates/mpos/admin/reports/earnings_control.tpl
Normal file
@ -0,0 +1,55 @@
|
||||
<form action="{$smarty.server.PHP_SELF}" method="post">
|
||||
<input type="hidden" name="page" value="{$smarty.request.page|escape}">
|
||||
<input type="hidden" name="action" value="{$smarty.request.action|escape}">
|
||||
<article class="module width_full">
|
||||
<header><h3>Earnings Information</h3></header>
|
||||
<table class="tablesorter">
|
||||
<tbody>
|
||||
<td align="left">
|
||||
<a href="{$smarty.server.PHP_SELF}?page={$smarty.request.page}&action={$smarty.request.action}&height={if is_array($REPORTDATA) && count($REPORTDATA) > ($BLOCKLIMIT - 1)}{$REPORTDATA[$BLOCKLIMIT - 1].height}{/if}&prev=1&limit={$BLOCKLIMIT}&id={$USERID}&filter={$FILTER}"<i class="icon-left-open"></i></a>
|
||||
</td>
|
||||
<td align="right">
|
||||
<a href="{$smarty.server.PHP_SELF}?page={$smarty.request.page}&action={$smarty.request.action}&height={if is_array($REPORTDATA) && count($REPORTDATA) > 0}{$REPORTDATA[0].height}{/if}&next=1&limit={$BLOCKLIMIT}&id={$USERID}&filter={$FILTER}"><i class="icon-right-open"></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="tablesorter">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<fieldset style="width:200px; padding-right:8px;">
|
||||
<label>Select User</label>
|
||||
{html_options name="id" options=$USERLIST selected=$USERID|default:"0"}
|
||||
</fieldset>
|
||||
</td>
|
||||
<td>
|
||||
<fieldset style="width:200px; padding-right:8px;">
|
||||
<label>Block Limit</label>
|
||||
<input size="10" type="text" name="limit" value="{$BLOCKLIMIT|default:"20"}" />
|
||||
</fieldset>
|
||||
</td>
|
||||
<td>
|
||||
<fieldset style="width:200px; padding-right:8px;">
|
||||
<label>Starting block height</label>
|
||||
<input type="text" class="pin" name="search" value="{$HEIGHT|default:"%"}">
|
||||
</fieldset>
|
||||
</td>
|
||||
<td align="center"><b>SHOW EMPTY ROUNDS</b><br><br>
|
||||
<span class="toggle">
|
||||
<label for="Show empty rounds">
|
||||
<input type="checkbox" class="ios-switch" name="filter" value="1" id="filter" {if $FILTER}checked{/if} />
|
||||
<div class="switch"></div>
|
||||
</label>
|
||||
</span>
|
||||
</td>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
<footer>
|
||||
<div class="submit_link">
|
||||
<input type="submit" value="Submit" class="alt_btn">
|
||||
</div>
|
||||
</footer>
|
||||
</article>
|
||||
</form>
|
||||
88
public/templates/mpos/admin/reports/earnings_report.tpl
Normal file
88
public/templates/mpos/admin/reports/earnings_report.tpl
Normal file
@ -0,0 +1,88 @@
|
||||
<article class="module width_full">
|
||||
<header><h3>Earnings Report Last {$BLOCKLIMIT} Blocks For User: {$USERNAME}</h3></header>
|
||||
<table class="tablesorter" cellspacing="0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th >Block</th>
|
||||
<th align="right">Round Shares</th>
|
||||
<th align="right">Round Valid</th>
|
||||
<th align="right">Invalid</th>
|
||||
<th align="right">Invalid %</th>
|
||||
<th align="right">Round %</th>
|
||||
<th align="right">PPLNS Shares</th>
|
||||
<th align="right">PPLNS Valid</th>
|
||||
<th align="right">Invalid</th>
|
||||
<th align="right">Invalid %</th>
|
||||
<th align="right">PPLNS %</th>
|
||||
<th align="right">Variance</th>
|
||||
<th align="right" style="padding-right: 25px;">Amount</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{assign var=percentage value=0}
|
||||
{assign var=percentage1 value=0}
|
||||
{assign var=percentage2 value=0}
|
||||
{assign var=totalvalid value=0}
|
||||
{assign var=totalinvalid value=0}
|
||||
{assign var=totalshares value=0}
|
||||
{assign var=usertotalshares value=0}
|
||||
{assign var=totalpercentage value=0}
|
||||
{assign var=pplnsshares value=0}
|
||||
{assign var=userpplnsshares value=0}
|
||||
{assign var=pplnsvalid value=0}
|
||||
{assign var=pplnsinvalid value=0}
|
||||
{assign var=amount value=0}
|
||||
{section txs $REPORTDATA}
|
||||
{assign var="totalshares" value=$totalshares+$REPORTDATA[txs].shares}
|
||||
{assign var=totalvalid value=$totalvalid+$REPORTDATA[txs]['user'].valid}
|
||||
{assign var=totalinvalid value=$totalinvalid+$REPORTDATA[txs]['user'].invalid}
|
||||
{assign var="pplnsshares" value=$pplnsshares+$REPORTDATA[txs].pplns_shares}
|
||||
{assign var=pplnsvalid value=$pplnsvalid+$REPORTDATA[txs]['user'].pplns_valid}
|
||||
{assign var=pplnsinvalid value=$pplnsinvalid+$REPORTDATA[txs]['user'].pplns_invalid}
|
||||
{assign var=amount value=$amount+$REPORTDATA[txs].user_credit}
|
||||
{if $REPORTDATA[txs]['user'].pplns_valid > 0}
|
||||
{assign var="userpplnsshares" value=$userpplnsshares+$REPORTDATA[txs].pplns_shares}
|
||||
{/if}
|
||||
{if $REPORTDATA[txs]['user'].valid > 0}
|
||||
{assign var="usertotalshares" value=$usertotalshares+$REPORTDATA[txs].shares}
|
||||
{/if}
|
||||
<tr>
|
||||
<td><a href="{$smarty.server.PHP_SELF}?page=statistics&action=round&height={$REPORTDATA[txs].height}">{$REPORTDATA[txs].height|default:"0"}</a></td>
|
||||
<td align="right">{$REPORTDATA[txs].shares|default:"0"}</td>
|
||||
<td align="right">{$REPORTDATA[txs]['user'].valid|number_format|default:"0"}</td>
|
||||
<td align="right">{$REPORTDATA[txs]['user'].invalid|number_format|default:"0"}</td>
|
||||
<td align="right">{if $REPORTDATA[txs]['user'].invalid > 0 }{($REPORTDATA[txs]['user'].invalid / $REPORTDATA[txs]['user'].valid * 100)|number_format:"2"|default:"0"}{else}0.00{/if}</td>
|
||||
<td align="right">{if $REPORTDATA[txs]['user'].valid > 0 }{(( 100 / $REPORTDATA[txs].shares) * $REPORTDATA[txs]['user'].valid)|number_format:"2"}{else}0.00{/if}</td>
|
||||
<td align="right">{$REPORTDATA[txs].pplns_shares|number_format|default:"0"}</td>
|
||||
<td align="right">{$REPORTDATA[txs]['user'].pplns_valid|number_format|default:"0"}</td>
|
||||
<td align="right">{$REPORTDATA[txs]['user'].pplns_invalid|number_format|default:"0"}</td>
|
||||
<td align="right">{if $REPORTDATA[txs]['user'].pplns_invalid > 0 && $REPORTDATA[txs]['user'].pplns_valid > 0 }{($REPORTDATA[txs]['user'].pplns_invalid / $REPORTDATA[txs]['user'].pplns_valid * 100)|number_format:"2"|default:"0"}{else}0.00{/if}</td>
|
||||
<td align="right">{if $REPORTDATA[txs].shares > 0 && $REPORTDATA[txs]['user'].pplns_valid > 0}{(( 100 / $REPORTDATA[txs].pplns_shares) * $REPORTDATA[txs]['user'].pplns_valid)|number_format:"2"|default:"0"}{else}0.00{/if}</td>
|
||||
<td align="right">{if $REPORTDATA[txs]['user'].valid > 0 && $REPORTDATA[txs]['user'].pplns_valid > 0}{math assign="percentage1" equation=(100 / ((( 100 / $REPORTDATA[txs].shares) * $REPORTDATA[txs]['user'].valid) / (( 100 / $REPORTDATA[txs].pplns_shares) * $REPORTDATA[txs]['user'].pplns_valid)))}{else if $REPORTDATA[txs]['user'].pplns_valid == 0}{assign var=percentage1 value=0}{else}{assign var=percentage1 value=100}{/if}
|
||||
<font color="{if ($percentage1 >= 100)}green{else}red{/if}">{$percentage1|number_format:"2"|default:"0"}</font></b></td>
|
||||
<td align="right" style="padding-right: 25px;">{$REPORTDATA[txs].user_credit|default:"0"|number_format:"8"}</td>
|
||||
{assign var=percentage1 value=0}
|
||||
</tr>
|
||||
{/section}
|
||||
<tr>
|
||||
<td><b>Totals</b></td>
|
||||
<td align="right">{$totalshares|number_format}</td>
|
||||
<td align="right">{$totalvalid|number_format}</td>
|
||||
<td align="right">{$totalinvalid|number_format}</td>
|
||||
<td align="right">{if $totalinvalid > 0 && $totalvalid > 0 }{($totalinvalid / $totalvalid * 100)|number_format:"2"|default:"0"}{else}0.00{/if}</td>
|
||||
<td align="right">{if $usertotalshares > 0 && $totalvalid > 0}{(( 100 / $usertotalshares) * $totalvalid)|number_format:"2"|default:"0"}{else}0.00{/if}</td>
|
||||
<td align="right">{$pplnsshares|number_format}</td>
|
||||
<td align="right">{$pplnsvalid|number_format}</td>
|
||||
<td align="right">{$pplnsinvalid|number_format}</td>
|
||||
<td align="right">{if $pplnsinvalid > 0 && $pplnsvalid > 0 }{($pplnsinvalid / $pplnsvalid * 100)|number_format:"2"|default:"0"}{else}0.00{/if}</td>
|
||||
<td align="right">{if $userpplnsshares > 0 && $pplnsvalid > 0}{(( 100 / $userpplnsshares) * $pplnsvalid)|number_format:"2"|default:"0"}{else}0.00{/if}</td>
|
||||
<td align="right">{if $totalvalid > 0 && $pplnsvalid > 0}{math assign="percentage2" equation=(100 / ((( 100 / $usertotalshares) * $totalvalid) / (( 100 / $userpplnsshares) * $pplnsvalid)))}{else if $pplnsvalid == 0}{assign var=percentage2 value=0}{else}{assign var=percentage2 value=100}{/if}
|
||||
<font color="{if ($percentage2 >= 100)}green{else}red{/if}">{$percentage2|number_format:"2"|default:"0"}</font></b></td>
|
||||
<td align="right" style="padding-right: 25px;">{$amount|default:"0"|number_format:"8"}</td>
|
||||
{assign var=percentage2 value=0}
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<footer>
|
||||
</footer>
|
||||
</article>
|
||||
@ -157,6 +157,7 @@ $(document).ready(function(){
|
||||
$('#b-fee').html((parseFloat(data.getdashboarddata.data.personal.estimates.fee).toFixed(4)));
|
||||
$('#b-donation').html((parseFloat(data.getdashboarddata.data.personal.estimates.donation).toFixed(4)));
|
||||
{/literal}{else}{literal}
|
||||
$('#b-ppsunpaid').html((parseFloat(data.getdashboarddata.data.personal.shares.unpaid).toFixed(0)));
|
||||
$('#b-ppsdiff').html((parseFloat(data.getdashboarddata.data.personal.sharedifficulty).toFixed(2)));
|
||||
$('#b-est1').html((parseFloat(data.getdashboarddata.data.personal.estimates.hours1).toFixed(8)));
|
||||
$('#b-est24hours').html((parseFloat(data.getdashboarddata.data.personal.estimates.hours24).toFixed(8)));
|
||||
|
||||
@ -10,8 +10,16 @@
|
||||
</tr>
|
||||
{elseif $GLOBAL.config.payout_system == 'pps'}
|
||||
<tr>
|
||||
<td><b>PPS Value</b></td>
|
||||
<td>{$GLOBAL.ppsvalue}</td>
|
||||
<td><b>Unpaid Shares</b></td>
|
||||
<td id="b-ppsunpaid">{$GLOBAL.userdata.pps.unpaidshares}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Baseline PPS Rate</b></td>
|
||||
<td>{$GLOBAL.ppsvalue} {$GLOBAL.config.currency}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Pools PPS Rate</b></td>
|
||||
<td>{$GLOBAL.poolppsvalue} {$GLOBAL.config.currency}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>PPS Difficulty</b></td>
|
||||
|
||||
@ -22,6 +22,8 @@
|
||||
<li class="icon-exchange"><a href="{$smarty.server.PHP_SELF}?page=admin&action=transactions">Transactions</a></li>
|
||||
<li class="icon-cog"><a href="{$smarty.server.PHP_SELF}?page=admin&action=settings">Settings</a></li>
|
||||
<li class="icon-doc"><a href="{$smarty.server.PHP_SELF}?page=admin&action=news">News</a></li>
|
||||
<li class="icon-chart"><a href="{$smarty.server.PHP_SELF}?page=admin&action=reports">Reports</a></li>
|
||||
<li class="icon-photo"><a href="{$smarty.server.PHP_SELF}?page=admin&action=poolworkers">Pool Workers</a></li>
|
||||
</ul>
|
||||
{/if}
|
||||
{if $smarty.session.AUTHENTICATED|default}
|
||||
|
||||
@ -103,14 +103,13 @@
|
||||
<td align="right">{$BLOCKSFOUND[block].difficulty|number_format:"2"}</td>
|
||||
<td align="right">{$BLOCKSFOUND[block].amount|number_format:"2"}</td>
|
||||
<td align="right">
|
||||
{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}
|
||||
{assign var="totalexpectedshares" value=$totalexpectedshares+$BLOCKSFOUND[block].estshares}
|
||||
{$BLOCKSFOUND[block].estshares|number_format}
|
||||
</td>
|
||||
{if $GLOBAL.config.payout_system == 'pplns'}<td align="right">{$BLOCKSFOUND[block].pplns_shares|number_format}</td>{/if}
|
||||
<td align="right">{$BLOCKSFOUND[block].shares|number_format}</td>
|
||||
<td align="right" style="padding-right: 25px;">
|
||||
{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=$BLOCKSFOUND[block].estshares}
|
||||
{assign var="totalpercentage" value=$totalpercentage+$percentage}
|
||||
<font color="{if ($percentage <= 100)}green{else}red{/if}">{$percentage|number_format:"2"}</font>
|
||||
</td>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user