Merge pull request #2338 from MPOS/development

UPDATE : Development to Master
This commit is contained in:
Sebastian Grewe 2014-10-14 14:36:12 +02:00
commit b10c328f09
21 changed files with 1521 additions and 119 deletions

View File

@ -1,12 +1,7 @@
Description Description
=========== ===========
MPOS is a web based Mining Portal for various crypto currencies. It was created by [TheSerapher](https://github.com/TheSerapher) and has hence grown quite large. Recently it was migrated into a Github Organization to make development easier. It's a community driven open source project. Support can be requested on IRC at https://webchat.freenode.net/?channels=#mpos MPOS is a web based Mining Portal for various crypto currencies. It was created by [TheSerapher](https://github.com/TheSerapher) and has hence grown quite large. Recently it was migrated into a Github Organization to make development easier. It's a community driven open source project. Support can be requested on IRC at https://webchat.freenode.net/?channels=#mpos - Be **PATIENT** ... People listed in this channel may currently be inactive but most users there have offline logging of messages. They **will** see your questions and answer if they can. Don't join, ask the question and leave. Sit around if you want answers to your questions!
**NOTE**: This project is still under development and commits are happening on a daily basis.
I do not recommend using this for a live setup as of yet. Wait for the later Release Candidate
if you wish to run your pool with it. Testing pools are much appreciated though!
Donations Donations
========= =========
@ -24,7 +19,7 @@ Donations to this project are going directly to [TheSerapher](https://github.com
Website Footer Website Footer
============== ==============
When you decide to use `MPOS` please be so kind and leave the footer intact. You are not the author of the software and should honor those that have worked on it. I don't mind changing the LTC donation address at the bottom, but keep in mind who really wrote this software and would deserve those ;-). When you decide to use `MPOS` please be so kind and leave the footer intact. You are not the author of the software and should honor those that have worked on it. Keeping the footer intact helps spreading the word. Leaving the donation address untouched allows miners to donate to the author.
Donors Donors
====== ======
@ -109,7 +104,6 @@ The following feature have been implemented so far:
* Pool Settings * Pool Settings
* Pool Workers * Pool Workers
* User Reports * User Reports
* Template Overwrite
* Notification system * Notification system
* IDLE Workers * IDLE Workers
* New blocks found in pool * New blocks found in pool
@ -125,7 +119,7 @@ The following feature have been implemented so far:
Installation Installation
============ ============
Please take a look at the [Quick Start Guide](https://github.com/TheSerapher/php-mpos/wiki/Quick-Start-Guide). This will give you an idea how to setup `MPOS`. Please take a look at the [Quick Start Guide](https://github.com/TheSerapher/php-mpos/wiki/Quick-Start-Guide). This will give you an idea how to setup `MPOS`. Please be aware that the `master` branch is our currently considered stable system while `development` is used as a test bed for all upcoming changes for `master`. If you wish to run a stable, well tested system ensure you run `git checkout master`. If you decide to stick to the `development` branch with bleeding edge code and potential bugs, just `git clone` the project.
Customization Customization
============= =============
@ -177,7 +171,7 @@ You can find the team on Freenode.net, #MPOS.
Team Members Team Members
============ ============
Author and Github Owner: [TheSerapher](https://github.com/TheSerapher) aka Sebastian Grewe Author and Project Owner: [TheSerapher](https://github.com/TheSerapher) aka Sebastian Grewe
Developers: Developers:

View File

@ -38,6 +38,10 @@ if (empty($aAllBlocks)) {
$monitoring->endCronjob($cron_name, 'E0011', 0, true, false); $monitoring->endCronjob($cron_name, 'E0011', 0, true, false);
} }
// Fetch precision
$precision = $coin->getCoinValuePrevision();
$table_precision = $coin->getCoinValuePrevision() + 3;
$log->logDebug('Starting PPLNS payout process'); $log->logDebug('Starting PPLNS payout process');
$count = 0; $count = 0;
foreach ($aAllBlocks as $iIndex => $aBlock) { foreach ($aAllBlocks as $iIndex => $aBlock) {
@ -181,7 +185,7 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
} }
// Table header for account shares // Table header for account shares
$strLogMask = "| %5.5s | %-15.15s | %15.15s | %15.15s | %12.12s | %15.15s | %15.15s | %15.15s | %15.15s |"; $strLogMask = "| %5.5s | %-15.15s | %15.15s | %15.15s | %12.12s | %${table_precision}.${table_precision}s | %${table_precision}.${table_precision}s | %${table_precision}.${table_precision}s | %${table_precision}.${table_precision}s |";
$log->logInfo(sprintf($strLogMask, 'ID', 'Username', 'Valid', 'Invalid', 'Percentage', 'Payout', 'Donation', 'Fee', 'Bonus')); $log->logInfo(sprintf($strLogMask, 'ID', 'Username', 'Valid', 'Invalid', 'Percentage', 'Payout', 'Donation', 'Fee', 'Bonus'));
// Loop through all accounts that have found shares for this round // Loop through all accounts that have found shares for this round
@ -197,7 +201,7 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
// Payout based on PPLNS target shares, proportional payout for all users // Payout based on PPLNS target shares, proportional payout for all users
$aData['percentage'] = round(( 100 / $iRoundShares) * $aData['pplns_valid'], 8); $aData['percentage'] = round(( 100 / $iRoundShares) * $aData['pplns_valid'], 8);
$aData['payout'] = round(( $aData['percentage'] / 100 ) * $dReward, 8); $aData['payout'] = ( $aData['percentage'] / 100 ) * $dReward;
// Defaults // Defaults
$aData['fee' ] = 0; $aData['fee' ] = 0;
$aData['donation'] = 0; $aData['donation'] = 0;
@ -205,19 +209,19 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
// Calculate pool fees // Calculate pool fees
if ($config['fees'] > 0 && $aData['no_fees'] == 0) if ($config['fees'] > 0 && $aData['no_fees'] == 0)
$aData['fee'] = round($config['fees'] / 100 * $aData['payout'], 8); $aData['fee'] = $config['fees'] / 100 * $aData['payout'];
// Calculate pool bonus if it applies, will be paid from liquid assets! // Calculate pool bonus if it applies, will be paid from liquid assets!
if ($config['pool_bonus'] > 0) { if ($config['pool_bonus'] > 0) {
if ($config['pool_bonus_type'] == 'block') { if ($config['pool_bonus_type'] == 'block') {
$aData['pool_bonus'] = round(( $config['pool_bonus'] / 100 ) * $dReward, 8); $aData['pool_bonus'] = ( $config['pool_bonus'] / 100 ) * $dReward;
} else { } else {
$aData['pool_bonus'] = round(( $config['pool_bonus'] / 100 ) * $aData['payout'], 8); $aData['pool_bonus'] = ( $config['pool_bonus'] / 100 ) * $aData['payout'];
} }
} }
// Calculate donation amount, fees not included // Calculate donation amount, fees not included
$aData['donation'] = round($user->getDonatePercent($user->getUserId($aData['username'])) / 100 * ( $aData['payout'] - $aData['fee']), 8); $aData['donation'] = $user->getDonatePercent($user->getUserId($aData['username'])) / 100 * ( $aData['payout'] - $aData['fee']);
// Verbose output of this users calculations // Verbose output of this users calculations
$log->logInfo( $log->logInfo(

View File

@ -63,7 +63,7 @@ if ($config['pps']['reward']['type'] == 'blockavg' && $block->getBlockCount() >
} }
// Per-share value to be paid out to users // Per-share value to be paid out to users
$pps_value = round($coin->calcPPSValue($pps_reward, $dDifficulty), 12); $pps_value = $coin->calcPPSValue($pps_reward, $dDifficulty);
// Find our last share accounted and last inserted share for PPS calculations // Find our last share accounted and last inserted share for PPS calculations
if (!$iPreviousShareId = $setting->getValue('pps_last_share_id')) { if (!$iPreviousShareId = $setting->getValue('pps_last_share_id')) {
@ -89,13 +89,15 @@ $log->logInfo("\tQuery Completed...");
if (!empty($aAccountShares)) { if (!empty($aAccountShares)) {
// Runtime information for this payout // Runtime information for this payout
$precision = $coin->getCoinValuePrevision();
$table_precision = $coin->getCoinValuePrevision() + 3;
$log->logInfo('Runtime information for this payout'); $log->logInfo('Runtime information for this payout');
$strLogMask = "| %-15.15s | %15.15s | %15.15s | %15.15s |"; $strLogMask = "| %-15.15s | %15.15s | %15.15s | %${table_precision}.${table_precision}s | %3.3s |";
$log->logInfo(sprintf($strLogMask, 'PPS reward type', 'Reward Base', 'Difficulty', 'PPS Value')); $log->logInfo(sprintf($strLogMask, 'PPS reward type', 'Reward Base', 'Difficulty', 'PPS Value', 'Precision'));
$log->logInfo(sprintf($strLogMask, $strRewardType, $pps_reward, $dDifficulty, $pps_value)); $log->logInfo(sprintf($strLogMask, $strRewardType, $pps_reward, $dDifficulty, $pps_value, $precision));
$log->logInfo('Per-user payout information'); $log->logInfo('Per-user payout information');
$strLogMask = "| %8.8s | %25.25s | %15.15s | %15.15s | %18.18s | %18.18s | %18.18s |"; $strLogMask = "| %8.8s | %25.25s | %15.15s | %${table_precision}.${table_precision}s | %${table_precision}.${table_precision}s | %${table_precision}.${table_precision}s | %${table_precision}.${table_precision}s |";
$log->logInfo(sprintf($strLogMask, 'User ID', 'Username', 'Invalid', 'Valid', ' * PPS Value', ' = Payout', 'Donation', 'Fee')); $log->logInfo(sprintf($strLogMask, 'User ID', 'Username', 'Invalid', 'Valid', '* PPS Value', ' = Payout', 'Donation', 'Fee'));
} }
foreach ($aAccountShares as $aData) { foreach ($aAccountShares as $aData) {
@ -106,7 +108,7 @@ foreach ($aAccountShares as $aData) {
} }
// Payout for this user // Payout for this user
$aData['payout'] = round($aData['valid'] * $pps_value, 12); $aData['payout'] = $aData['valid'] * $pps_value;
// Defaults // Defaults
$aData['fee' ] = 0; $aData['fee' ] = 0;
@ -114,13 +116,13 @@ foreach ($aAccountShares as $aData) {
// Calculate block fees // Calculate block fees
if ($config['fees'] > 0 && $aData['no_fees'] == 0) if ($config['fees'] > 0 && $aData['no_fees'] == 0)
$aData['fee'] = round($config['fees'] / 100 * $aData['payout'], 12); $aData['fee'] = $config['fees'] / 100 * $aData['payout'];
// Calculate donation amount // Calculate donation amount
$aData['donation'] = round($user->getDonatePercent($user->getUserId($aData['username'])) / 100 * ( $aData['payout'] - $aData['fee']), 12); $aData['donation'] = $user->getDonatePercent($user->getUserId($aData['username'])) / 100 * ( $aData['payout'] - $aData['fee']);
$log->logInfo(sprintf( $log->logInfo(sprintf(
$strLogMask, $aData['id'], $aData['username'], $aData['invalid'], $aData['valid'], $strLogMask, $aData['id'], $aData['username'], $aData['invalid'], $aData['valid'],
number_format($pps_value, 12), number_format($aData['payout'], 12), number_format($aData['donation'], 12), number_format($aData['fee'], 12) number_format($pps_value, $precision), number_format($aData['payout'], $precision), number_format($aData['donation'], $precision), number_format($aData['fee'], $precision)
)); ));
// Add new credit transaction // Add new credit transaction

View File

@ -38,9 +38,13 @@ if (empty($aAllBlocks)) {
$monitoring->endCronjob($cron_name, 'E0011', 0, true, false); $monitoring->endCronjob($cron_name, 'E0011', 0, true, false);
} }
// Fetch precision
$precision = $coin->getCoinValuePrevision();
$table_precision = $coin->getCoinValuePrevision() + 3;
$count = 0; $count = 0;
// Table header for account shares // Table header for account shares
$strLogMask = "| %10.10s | %-5.5s | %15.15s | %15.15s | %12.12s | %12.12s | %15.15s | %15.15s | %15.15s | %15.15s |"; $strLogMask = "| %10.10s | %-5.5s | %15.15s | %15.15s | %12.12s | %12.12s | %${table_precision}.${table_precision}s | %${table_precision}.${table_precision}s | %${table_precision}.${table_precision}s | %${table_precision}.${table_precision}s |";
$log->logInfo(sprintf($strLogMask, 'Block', 'ID', 'Username', 'Valid', 'Invalid', 'Percentage', 'Payout', 'Donation', 'Fee', 'Bonus')); $log->logInfo(sprintf($strLogMask, 'Block', 'ID', 'Username', 'Valid', 'Invalid', 'Percentage', 'Payout', 'Donation', 'Fee', 'Bonus'));
foreach ($aAllBlocks as $iIndex => $aBlock) { foreach ($aAllBlocks as $iIndex => $aBlock) {
// If we have unaccounted blocks without share_ids, they might not have been inserted yet // If we have unaccounted blocks without share_ids, they might not have been inserted yet
@ -87,29 +91,29 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
$aData['fee' ] = 0; $aData['fee' ] = 0;
$aData['donation'] = 0; $aData['donation'] = 0;
$aData['pool_bonus'] = 0; $aData['pool_bonus'] = 0;
$aData['percentage'] = round(( 100 / $iRoundShares ) * $aData['valid'], 8); $aData['percentage'] = ( 100 / $iRoundShares ) * $aData['valid'];
$aData['payout'] = round(( $aData['percentage'] / 100 ) * $dReward, 8); $aData['payout'] = ( $aData['percentage'] / 100 ) * $dReward;
// Calculate pool fees if they apply // Calculate pool fees if they apply
if ($config['fees'] > 0 && $aData['no_fees'] == 0) if ($config['fees'] > 0 && $aData['no_fees'] == 0)
$aData['fee'] = round($config['fees'] / 100 * $aData['payout'], 8); $aData['fee'] = $config['fees'] / 100 * $aData['payout'];
// Calculate pool bonus if it applies, will be paid from liquid assets! // Calculate pool bonus if it applies, will be paid from liquid assets!
if ($config['pool_bonus'] > 0) { if ($config['pool_bonus'] > 0) {
if ($config['pool_bonus_type'] == 'block') { if ($config['pool_bonus_type'] == 'block') {
$aData['pool_bonus'] = round(( $config['pool_bonus'] / 100 ) * $dReward, 8); $aData['pool_bonus'] = ( $config['pool_bonus'] / 100 ) * $dReward;
} else { } else {
$aData['pool_bonus'] = round(( $config['pool_bonus'] / 100 ) * $aData['payout'], 8); $aData['pool_bonus'] = ( $config['pool_bonus'] / 100 ) * $aData['payout'];
} }
} }
// Calculate donation amount, fees not included // Calculate donation amount, fees not included
$aData['donation'] = round($user->getDonatePercent($user->getUserId($aData['username'])) / 100 * ( $aData['payout'] - $aData['fee']), 8); $aData['donation'] = $user->getDonatePercent($user->getUserId($aData['username'])) / 100 * ( $aData['payout'] - $aData['fee']);
// Verbose output of this users calculations // Verbose output of this users calculations
$log->logInfo( $log->logInfo(
sprintf($strLogMask, $aBlock['height'], $aData['id'], $aData['username'], $aData['valid'], $aData['invalid'], sprintf($strLogMask, $aBlock['height'], $aData['id'], $aData['username'], $aData['valid'], $aData['invalid'],
number_format($aData['percentage'], 8), number_format($aData['payout'], 8), number_format($aData['donation'], 8), number_format($aData['fee'], 8), number_format($aData['pool_bonus'], 8)) number_format($aData['percentage'], $precision), number_format($aData['payout'], $precision), number_format($aData['donation'], $precision), number_format($aData['fee'], $precision), number_format($aData['pool_bonus'], $precision))
); );
// Update user share statistics // Update user share statistics

View File

@ -34,13 +34,18 @@ if (file_exists(CLASS_DIR . '/coins/coin_' . $config['algorithm'] . '.class.php'
require_once(INCLUDE_DIR . '/lib/swiftmailer/swift_required.php'); require_once(INCLUDE_DIR . '/lib/swiftmailer/swift_required.php');
// Detect device // Detect device
if ( PHP_SAPI == 'cli') { require_once(INCLUDE_DIR . '/lib/Mobile_Detect.php');
$detect = new Mobile_Detect;
if ($detect->isMobile()) {
$theme = $setting->getValue('website_mobile_theme', 'bootstrap');
} else if ( PHP_SAPI == 'cli') {
// Create a new compile folder just for crons // Create a new compile folder just for crons
// We call mail templates directly anyway // We call mail templates directly anyway
$theme = 'cron'; $theme = 'cron';
} else { } else {
// Use configured theme, fallback to default theme // Use configured theme, fallback to default theme
$setting->getValue('website_theme') ? $theme = $setting->getValue('website_theme') : $theme = 'bootstrap'; $theme = $setting->getValue('website_theme', 'bootstrap');
} }
define('THEME', $theme); define('THEME', $theme);

View File

@ -15,6 +15,9 @@ class CoinBase extends Base {
// Our coins share difficulty precision // Our coins share difficulty precision
protected $share_difficulty_precision = 0; protected $share_difficulty_precision = 0;
// Our coin value precision, mostly used on frontend
protected $coin_value_precision = 8;
/** /**
* Read our target bits * Read our target bits
**/ **/
@ -22,6 +25,13 @@ class CoinBase extends Base {
return $this->target_bits; return $this->target_bits;
} }
/**
* Read our coin value precision
**/
public function getCoinValuePrevision() {
return $this->coin_value_precision;
}
/** /**
* Read our share difficulty precision * Read our share difficulty precision
**/ **/

View File

@ -8,6 +8,7 @@ $defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
**/ **/
class Coin extends CoinBase { class Coin extends CoinBase {
protected $target_bits = 32; protected $target_bits = 32;
protected $coin_value_precision = 20;
} }
?> ?>

View File

@ -16,8 +16,9 @@ class Transaction extends Base {
* @return bool * @return bool
**/ **/
public function addTransaction($account_id, $amount, $type='Credit', $block_id=NULL, $coin_address=NULL, $txid=NULL) { public function addTransaction($account_id, $amount, $type='Credit', $block_id=NULL, $coin_address=NULL, $txid=NULL) {
$amount = number_format($amount, $this->coin->getCoinValuePrevision(), '.', '');
$stmt = $this->mysqli->prepare("INSERT INTO $this->table (account_id, amount, block_id, type, coin_address, txid) VALUES (?, ?, ?, ?, ?, ?)"); $stmt = $this->mysqli->prepare("INSERT INTO $this->table (account_id, amount, block_id, type, coin_address, txid) VALUES (?, ?, ?, ?, ?, ?)");
if ($this->checkStmt($stmt) && $stmt->bind_param("idisss", $account_id, $amount, $block_id, $type, $coin_address, $txid) && $stmt->execute()) { if ($this->checkStmt($stmt) && $stmt->bind_param("isisss", $account_id, $amount, $block_id, $type, $coin_address, $txid) && $stmt->execute()) {
$this->insert_id = $stmt->insert_id; $this->insert_id = $stmt->insert_id;
return true; return true;
} }
@ -296,11 +297,11 @@ class Transaction extends Base {
$this->debug->append("STA " . __METHOD__, 4); $this->debug->append("STA " . __METHOD__, 4);
$stmt = $this->mysqli->prepare(" $stmt = $this->mysqli->prepare("
SELECT SELECT
ROUND(( (
SUM( IF( ( t.type IN ('Credit','Bonus') AND b.confirmations >= ? ) OR t.type = 'Credit_PPS', t.amount, 0 ) ) - SUM( IF( ( t.type IN ('Credit','Bonus') AND b.confirmations >= ? ) OR t.type = 'Credit_PPS', t.amount, 0 ) ) -
SUM( IF( t.type IN ('Debit_MP', 'Debit_AP'), t.amount, 0 ) ) - SUM( IF( t.type IN ('Debit_MP', 'Debit_AP'), t.amount, 0 ) ) -
SUM( IF( ( t.type IN ('Donation','Fee') AND b.confirmations >= ? ) OR ( t.type IN ('Donation_PPS', 'Fee_PPS', 'TXFee') ), t.amount, 0 ) ) SUM( IF( ( t.type IN ('Donation','Fee') AND b.confirmations >= ? ) OR ( t.type IN ('Donation_PPS', 'Fee_PPS', 'TXFee') ), t.amount, 0 ) )
), 8) AS balance ) AS balance
FROM $this->table AS t FROM $this->table AS t
LEFT JOIN " . $this->block->getTableName() . " AS b LEFT JOIN " . $this->block->getTableName() . " AS b
ON t.block_id = b.id ON t.block_id = b.id
@ -319,19 +320,19 @@ class Transaction extends Base {
$this->debug->append("STA " . __METHOD__, 4); $this->debug->append("STA " . __METHOD__, 4);
$stmt = $this->mysqli->prepare(" $stmt = $this->mysqli->prepare("
SELECT SELECT
IFNULL(ROUND(( IFNULL((
SUM( IF( ( t.type IN ('Credit','Bonus') AND b.confirmations >= ? ) OR t.type = 'Credit_PPS', t.amount, 0 ) ) - SUM( IF( ( t.type IN ('Credit','Bonus') AND b.confirmations >= ? ) OR t.type = 'Credit_PPS', t.amount, 0 ) ) -
SUM( IF( t.type IN ('Debit_MP', 'Debit_AP'), t.amount, 0 ) ) - SUM( IF( t.type IN ('Debit_MP', 'Debit_AP'), t.amount, 0 ) ) -
SUM( IF( ( t.type IN ('Donation','Fee') AND b.confirmations >= ? ) OR ( t.type IN ('Donation_PPS', 'Fee_PPS', 'TXFee') ), t.amount, 0 ) ) SUM( IF( ( t.type IN ('Donation','Fee') AND b.confirmations >= ? ) OR ( t.type IN ('Donation_PPS', 'Fee_PPS', 'TXFee') ), t.amount, 0 ) )
), 8), 0) AS confirmed, ), 0) AS confirmed,
IFNULL(ROUND(( IFNULL((
SUM( IF( t.type IN ('Credit','Bonus') AND b.confirmations < ? AND b.confirmations >= 0, t.amount, 0 ) ) - SUM( IF( t.type IN ('Credit','Bonus') AND b.confirmations < ? AND b.confirmations >= 0, t.amount, 0 ) ) -
SUM( IF( t.type IN ('Donation','Fee') AND b.confirmations < ? AND b.confirmations >= 0, t.amount, 0 ) ) SUM( IF( t.type IN ('Donation','Fee') AND b.confirmations < ? AND b.confirmations >= 0, t.amount, 0 ) )
), 8), 0) AS unconfirmed, ), 0) AS unconfirmed,
IFNULL(ROUND(( IFNULL((
SUM( IF( t.type IN ('Credit','Bonus') AND b.confirmations = -1, t.amount, 0) ) - SUM( IF( t.type IN ('Credit','Bonus') AND b.confirmations = -1, t.amount, 0) ) -
SUM( IF( t.type IN ('Donation','Fee') AND b.confirmations = -1, t.amount, 0) ) SUM( IF( t.type IN ('Donation','Fee') AND b.confirmations = -1, t.amount, 0) )
), 8), 0) AS orphaned ), 0) AS orphaned
FROM $this->table AS t FROM $this->table AS t
LEFT JOIN " . $this->block->getTableName() . " AS b LEFT JOIN " . $this->block->getTableName() . " AS b
ON t.block_id = b.id ON t.block_id = b.id
@ -357,12 +358,10 @@ class Transaction extends Base {
a.ap_threshold, a.ap_threshold,
ca.coin_address, ca.coin_address,
IFNULL( IFNULL(
ROUND(
( (
SUM( IF( ( t.type IN ('Credit','Bonus') AND b.confirmations >= " . $this->config['confirmations'] . ") OR t.type = 'Credit_PPS', t.amount, 0 ) ) - SUM( IF( ( t.type IN ('Credit','Bonus') AND b.confirmations >= " . $this->config['confirmations'] . ") OR t.type = 'Credit_PPS', t.amount, 0 ) ) -
SUM( IF( t.type IN ('Debit_MP', 'Debit_AP'), t.amount, 0 ) ) - SUM( IF( t.type IN ('Debit_MP', 'Debit_AP'), t.amount, 0 ) ) -
SUM( IF( ( t.type IN ('Donation','Fee') AND b.confirmations >= " . $this->config['confirmations'] . ") OR ( t.type IN ('Donation_PPS', 'Fee_PPS', 'TXFee') ), t.amount, 0 ) ) SUM( IF( ( t.type IN ('Donation','Fee') AND b.confirmations >= " . $this->config['confirmations'] . ") OR ( t.type IN ('Donation_PPS', 'Fee_PPS', 'TXFee') ), t.amount, 0 ) )
), 8
), 0 ), 0
) AS confirmed ) AS confirmed
FROM $this->table AS t FROM $this->table AS t
@ -451,12 +450,10 @@ class Transaction extends Base {
ca.coin_address, ca.coin_address,
p.id AS payout_id, p.id AS payout_id,
IFNULL( IFNULL(
ROUND(
( (
SUM( IF( ( t.type IN ('Credit','Bonus') AND b.confirmations >= " . $this->config['confirmations'] . ") OR t.type = 'Credit_PPS', t.amount, 0 ) ) - SUM( IF( ( t.type IN ('Credit','Bonus') AND b.confirmations >= " . $this->config['confirmations'] . ") OR t.type = 'Credit_PPS', t.amount, 0 ) ) -
SUM( IF( t.type IN ('Debit_MP', 'Debit_AP'), t.amount, 0 ) ) - SUM( IF( t.type IN ('Debit_MP', 'Debit_AP'), t.amount, 0 ) ) -
SUM( IF( ( t.type IN ('Donation','Fee') AND b.confirmations >= " . $this->config['confirmations'] . ") OR ( t.type IN ('Donation_PPS', 'Fee_PPS', 'TXFee') ), t.amount, 0 ) ) SUM( IF( ( t.type IN ('Donation','Fee') AND b.confirmations >= " . $this->config['confirmations'] . ") OR ( t.type IN ('Donation_PPS', 'Fee_PPS', 'TXFee') ), t.amount, 0 ) )
), 8
), 0 ), 0
) AS confirmed ) AS confirmed
FROM " . $this->payout->getTableName() . " AS p FROM " . $this->payout->getTableName() . " AS p
@ -481,7 +478,9 @@ class Transaction extends Base {
$transaction = new Transaction(); $transaction = new Transaction();
$transaction->setMemcache($memcache); $transaction->setMemcache($memcache);
$transaction->setNotification($notification); $transaction->setNotification($notification);
$transaction->setSetting($setting);
$transaction->setDebug($debug); $transaction->setDebug($debug);
$transaction->setCoin($coin);
$transaction->setCoinAddress($coin_address); $transaction->setCoinAddress($coin_address);
$transaction->setMysql($mysqli); $transaction->setMysql($mysqli);
$transaction->setConfig($config); $transaction->setConfig($config);

View File

@ -69,6 +69,13 @@ $aSettings['website'][] = array(
'name' => 'website_theme', 'value' => $setting->getValue('website_theme'), 'name' => 'website_theme', 'value' => $setting->getValue('website_theme'),
'tooltip' => 'The default theme used on your pool.' 'tooltip' => 'The default theme used on your pool.'
); );
$aSettings['website'][] = array(
'display' => 'Website mobile theme', 'type' => 'select',
'options' => $aThemes,
'default' => 'bootstrap',
'name' => 'website_mobile_theme', 'value' => $setting->getValue('website_mobile_theme'),
'tooltip' => 'The mobile theme used on your pool.'
);
$aSettings['website'][] = array( $aSettings['website'][] = array(
'display' => 'Website Design', 'type' => 'select', 'display' => 'Website Design', 'type' => 'select',
'options' => $aDesigns, 'options' => $aDesigns,
@ -317,7 +324,7 @@ $aSettings['system'][] = array(
); );
$aSettings['system'][] = array( $aSettings['system'][] = array(
'display' => 'Date format string', 'type' => 'text', 'display' => 'Date format string', 'type' => 'text',
'site' => 25, 'size' => 25,
'default' => '%m/%d/%Y %H:%M:%S', 'default' => '%m/%d/%Y %H:%M:%S',
'name' => 'system_date_format', 'value' => $setting->getValue('system_date_format'), 'name' => 'system_date_format', 'value' => $setting->getValue('system_date_format'),
'tooltip' => 'Date format to be used throughout the site. Please check PHP strftime for details.' 'tooltip' => 'Date format to be used throughout the site. Please check PHP strftime for details.'

File diff suppressed because one or more lines are too long

View File

@ -49,6 +49,7 @@ if ($user->isAuthenticated()) {
} }
// Make it available in Smarty // Make it available in Smarty
$smarty->assign('PRECISION', $coin->getCoinValuePrevision());
$smarty->assign('BLOCKSFOUND', $aLastBlocks); $smarty->assign('BLOCKSFOUND', $aLastBlocks);
$smarty->assign('DISABLED_DASHBOARD', $setting->getValue('disable_dashboard')); $smarty->assign('DISABLED_DASHBOARD', $setting->getValue('disable_dashboard'));
$smarty->assign('DISABLED_DASHBOARD_API', $setting->getValue('disable_dashboard_api')); $smarty->assign('DISABLED_DASHBOARD_API', $setting->getValue('disable_dashboard_api'));

View File

@ -176,7 +176,8 @@ if (@$_SESSION['USERDATA']['id']) {
break; break;
case 'pps': case 'pps':
$aGlobal['userdata']['pps']['unpaidshares'] = $statistics->getUserUnpaidPPSShares($_SESSION['USERDATA']['username'], $_SESSION['USERDATA']['id'], $setting->getValue('pps_last_share_id')); $aGlobal['userdata']['pps']['unpaidshares'] = $statistics->getUserUnpaidPPSShares($_SESSION['USERDATA']['username'], $_SESSION['USERDATA']['id'], $setting->getValue('pps_last_share_id'));
$aGlobal['ppsvalue'] = number_format($statistics->getPPSValue(), 12); // We use coin precision + 8 to display PPS value
$aGlobal['ppsvalue'] = number_format($statistics->getPPSValue(), $coin->getCoinValuePrevision() + 8);
$aGlobal['poolppsvalue'] = $aGlobal['ppsvalue'] * pow(2, $config['difficulty'] - 16); $aGlobal['poolppsvalue'] = $aGlobal['ppsvalue'] * pow(2, $config['difficulty'] - 16);
$aGlobal['userdata']['estimates'] = $statistics->getUserEstimates($aGlobal['userdata']['sharerate'], $aGlobal['userdata']['sharedifficulty'], $aGlobal['userdata']['donate_percent'], $aGlobal['userdata']['no_fees'], $aGlobal['ppsvalue']); $aGlobal['userdata']['estimates'] = $statistics->getUserEstimates($aGlobal['userdata']['sharerate'], $aGlobal['userdata']['sharedifficulty'], $aGlobal['userdata']['donate_percent'], $aGlobal['userdata']['no_fees'], $aGlobal['ppsvalue']);
break; break;

View File

@ -2,7 +2,7 @@
$defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1; $defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
define('MPOS_VERSION', '0.0.4'); define('MPOS_VERSION', '0.0.4');
define('DB_VERSION', '0.0.14'); define('DB_VERSION', '0.0.15');
define('CONFIG_VERSION', '0.0.8'); define('CONFIG_VERSION', '0.0.8');
define('HASH_VERSION', 1); define('HASH_VERSION', 1);

View File

@ -144,7 +144,7 @@ CREATE TABLE IF NOT EXISTS `settings` (
UNIQUE KEY `setting` (`name`) UNIQUE KEY `setting` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `settings` (`name`, `value`) VALUES ('DB_VERSION', '0.0.13'); INSERT INTO `settings` (`name`, `value`) VALUES ('DB_VERSION', '0.0.15');
CREATE TABLE IF NOT EXISTS `shares` ( CREATE TABLE IF NOT EXISTS `shares` (
`id` bigint(30) NOT NULL AUTO_INCREMENT, `id` bigint(30) NOT NULL AUTO_INCREMENT,
@ -226,7 +226,7 @@ CREATE TABLE IF NOT EXISTS `transactions` (
`account_id` int(255) unsigned NOT NULL, `account_id` int(255) unsigned NOT NULL,
`type` varchar(25) DEFAULT NULL, `type` varchar(25) DEFAULT NULL,
`coin_address` varchar(255) DEFAULT NULL, `coin_address` varchar(255) DEFAULT NULL,
`amount` double DEFAULT '0', `amount` decimal(50,30) DEFAULT '0',
`block_id` int(255) DEFAULT NULL, `block_id` int(255) DEFAULT NULL,
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`txid` varchar(256) DEFAULT NULL, `txid` varchar(256) DEFAULT NULL,
@ -242,7 +242,7 @@ CREATE TABLE IF NOT EXISTS `transactions` (
CREATE TABLE `statistics_users` ( CREATE TABLE `statistics_users` (
`id` int(11) NOT NULL AUTO_INCREMENT, `id` int(11) NOT NULL AUTO_INCREMENT,
`account_id` int(11) NOT NULL, `account_id` int(11) NOT NULL,
`hashrate` int(11) NOT NULL, `hashrate` bigint(20) unsigned NOT NULL,
`workers` int(11) NOT NULL, `workers` int(11) NOT NULL,
`sharerate` float NOT NULL, `sharerate` float NOT NULL,
`timestamp` int(11) NOT NULL, `timestamp` int(11) NOT NULL,

View File

@ -13,7 +13,7 @@
<div class="col-lg-12"> <div class="col-lg-12">
<div class="form-group"> <div class="form-group">
<p style="padding-left:3px; padding-redight:30px; font-size:10px;"> <p style="padding-left:3px; padding-redight:30px; font-size:10px;">
Please note: a {if $GLOBAL.config.txfee_manual > 0.00001}{$GLOBAL.config.txfee_manual}{else}{$GLOBAL.config.txfee_manual|number_format:"8"}{/if} {$GLOBAL.config.currency} transaction will apply when processing "On-Demand" manual payments <span id="tt"><img width="15px" height="15px" title="This {if $GLOBAL.config.txfee_manual > 0.00001}{$GLOBAL.config.txfee_manual}{else}{$GLOBAL.config.txfee_manual|number_format:"8"}{/if} manual payment transaction fee is a network fee and goes back into the network not the pool." src="site_assets/bootstrap/images/questionmark.png"></span> {if $GLOBAL.config.txfee_manual > 0}Please note: a {if $GLOBAL.config.txfee_manual > 0.00001}{$GLOBAL.config.txfee_manual}{else}{$GLOBAL.config.txfee_manual|number_format:"8"}{/if} {$GLOBAL.config.currency} transaction will apply when processing "On-Demand" manual payments <span id="tt"><img width="15px" height="15px" title="This {if $GLOBAL.config.txfee_manual > 0.00001}{$GLOBAL.config.txfee_manual}{else}{$GLOBAL.config.txfee_manual|number_format:"8"}{/if} manual payment transaction fee is a network fee and goes back into the network not the pool." src="site_assets/bootstrap/images/questionmark.png"></span>{/if}
</p> </p>
<p style="padding-left:3px; padding-redight:30px; font-size:10px;"> <p style="padding-left:3px; padding-redight:30px; font-size:10px;">
Minimum Cashout: {$GLOBAL.config.mp_threshold} {$GLOBAL.config.currency} Minimum Cashout: {$GLOBAL.config.mp_threshold} {$GLOBAL.config.currency}

View File

@ -50,9 +50,9 @@
<div class="form-group"> <div class="form-group">
<label>Automatic Payout Threshold</label> <label>Automatic Payout Threshold</label>
</br> </br>
<font size="1">{$GLOBAL.config.ap_threshold.min} - {$GLOBAL.config.ap_threshold.max} {$GLOBAL.config.currency}. Set to '0' for no auto payout. A {if $GLOBAL.config.txfee_auto > 0.00001}{$GLOBAL.config.txfee_auto}{else}{$GLOBAL.config.txfee_auto|number_format:"8"}{/if} {$GLOBAL.config.currency} TX fee will apply <span id="tt"><img width="15px" height="15px" title="This {if $GLOBAL.config.txfee_auto > 0.00001}{$GLOBAL.config.txfee_auto}{else}{$GLOBAL.config.txfee_auto|number_format:"8"}{/if} automatic payment transaction fee is a network fee and goes back into the network not the pool." src="site_assets/bootstrap/images/questionmark.png"></span></font> <font size="1">{if $GLOBAL.config.ap_threshold.min < 0.0001}{$GLOBAL.config.ap_threshold.min|number_format:"8"}{else}{$GLOBAL.config.ap_threshold.min}{/if} - {if $GLOBAL.config.ap_threshold.max < 0.0001}{$GLOBAL.config.ap_threshold.max|number_format:"8"}{else}{$GLOBAL.config.ap_threshold.max}{/if} {$GLOBAL.config.currency}. Set to '0' for no auto payout.{if $GLOBAL.config.txfee_auto > 0} A {if $GLOBAL.config.txfee_auto > 0.00001}{$GLOBAL.config.txfee_auto}{else}{$GLOBAL.config.txfee_auto|number_format:"8"}{/if} {$GLOBAL.config.currency} TX fee will apply <span id="tt"><img width="15px" height="15px" title="This {if $GLOBAL.config.txfee_auto > 0.00001}{$GLOBAL.config.txfee_auto}{else}{$GLOBAL.config.txfee_auto|number_format:"8"}{/if} automatic payment transaction fee is a network fee and goes back into the network not the pool." src="site_assets/bootstrap/images/questionmark.png"></span>{/if}</font>
</br> </br>
<input class="form-control" type="text" name="payoutThreshold" value="{nocache}{$smarty.request.payoutThreshold|default:$GLOBAL.userdata.ap_threshold|escape}{/nocache}" size="{$GLOBAL.config.ap_threshold.max|strlen}" maxlength="{$GLOBAL.config.ap_threshold.max|strlen}" {if $GLOBAL.twofactor.enabled && $GLOBAL.twofactor.options.details && !$DETAILSUNLOCKED}id="disabledInput" disabled{/if}/> <input class="form-control" type="text" name="payoutThreshold" value="{nocache}{$smarty.request.payoutThreshold|default:$GLOBAL.userdata.ap_threshold|escape}{/nocache}" size="{$GLOBAL.config.ap_threshold.max|strlen+4}" maxlength="{if $GLOBAL.config.ap_threshold.max < 1}10{else}{$GLOBAL.config.ap_threshold.max|strlen}{/if}" {if $GLOBAL.twofactor.enabled && $GLOBAL.twofactor.options.details && !$DETAILSUNLOCKED}id="disabledInput" disabled{/if}/>
</div> </div>
<div class="form-group"> <div class="form-group">
<label>Anonymous Account</label> <label>Anonymous Account</label>
@ -66,7 +66,6 @@
<font size="1">The 4 digit PIN you chose when registering</font> <font size="1">The 4 digit PIN you chose when registering</font>
<input class="form-control" type="password" name="authPin" size="4" maxlength="4"> <input class="form-control" type="password" name="authPin" size="4" maxlength="4">
</div> </div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -134,18 +134,18 @@ $(document).ready(function(){
$('#b-nblock').html(data.getdashboarddata.data.network.block); $('#b-nblock').html(data.getdashboarddata.data.network.block);
$('#b-roundprogress').html(number_format(parseFloat(data.getdashboarddata.data.pool.shares.progress).toFixed(2), 2) + "%"); $('#b-roundprogress').html(number_format(parseFloat(data.getdashboarddata.data.pool.shares.progress).toFixed(2), 2) + "%");
{/literal}{if $GLOBAL.config.payout_system != 'pps'}{literal } {/literal}{if $GLOBAL.config.payout_system != 'pps'}{literal }
$('#b-payout').html(number_format(data.getdashboarddata.data.personal.estimates.payout, 8)); $('#b-payout').html(number_format(data.getdashboarddata.data.personal.estimates.payout, {/literal}{$PRECISION}{literal}));
$('#b-block').html(number_format(data.getdashboarddata.data.personal.estimates.block, 8)); $('#b-block').html(number_format(data.getdashboarddata.data.personal.estimates.block, {/literal}{$PRECISION}{literal}));
$('#b-fee').html(number_format(data.getdashboarddata.data.personal.estimates.fee,8 )); $('#b-fee').html(number_format(data.getdashboarddata.data.personal.estimates.fee, {/literal}{$PRECISION}{literal}));
$('#b-donation').html(number_format(data.getdashboarddata.data.personal.estimates.donation, 8)); $('#b-donation').html(number_format(data.getdashboarddata.data.personal.estimates.donation, {/literal}{$PRECISION}{literal}));
{/literal}{else}{literal} {/literal}{else}{literal}
$('#b-ppsunpaid').html(number_format(data.getdashboarddata.data.personal.shares.unpaid)); $('#b-ppsunpaid').html(number_format(data.getdashboarddata.data.personal.shares.unpaid));
$('#b-ppsdiff').html(number_format(data.getdashboarddata.data.personal.sharedifficulty, 2)); $('#b-ppsdiff').html(number_format(data.getdashboarddata.data.personal.sharedifficulty, 2));
$('#b-est1').html(number_format(data.getdashboarddata.data.personal.estimates.hours1, 8)); $('#b-est1').html(number_format(data.getdashboarddata.data.personal.estimates.hours1, {/literal}{$PRECISION}{literal}));
$('#b-est24hours').html(number_format(data.getdashboarddata.data.personal.estimates.hours24, 8)); $('#b-est24hours').html(number_format(data.getdashboarddata.data.personal.estimates.hours24, {/literal}{$PRECISION}{literal}));
$('#b-est7days').html(number_format(data.getdashboarddata.data.personal.estimates.days7, 8)); $('#b-est7days').html(number_format(data.getdashboarddata.data.personal.estimates.days7, {/literal}{$PRECISION}{literal}));
$('#b-est14days').html(number_format(data.getdashboarddata.data.personal.estimates.days14, 8)); $('#b-est14days').html(number_format(data.getdashboarddata.data.personal.estimates.days14, {/literal}{$PRECISION}{literal}));
$('#b-est30days').html(number_format(data.getdashboarddata.data.personal.estimates.days30, 8)); $('#b-est30days').html(number_format(data.getdashboarddata.data.personal.estimates.days30, {/literal}{$PRECISION}{literal}));
{/literal}{/if}{literal} {/literal}{/if}{literal}
{/literal}{if $GLOBAL.config.payout_system == 'pplns'}{literal} {/literal}{if $GLOBAL.config.payout_system == 'pplns'}{literal}
$('#b-pplns').html({/literal}{$GLOBAL.pplns.target}{literal}); $('#b-pplns').html({/literal}{$GLOBAL.pplns.target}{literal});

View File

@ -37,10 +37,10 @@
</div> </div>
<div class="circle-tile-content lightblue"> <div class="circle-tile-content lightblue">
<div class="circle-tile-description text-faded"> <div class="circle-tile-description text-faded">
<p class="h5 up-more" id="b-payout">{$GLOBAL.userdata.estimates.payout|number_format:"8"}</p> <p class="h5 up-more" id="b-payout">{$GLOBAL.userdata.estimates.payout|number_format:$PRECISION}</p>
</div> </div>
<div class="circle-tile-number text-faded"> <div class="circle-tile-number text-faded">
<p class="h6">{$GLOBAL.config.currency} Est Earnings</p> <p class="h6">{$GLOBAL.config.currency} Est. Earnings</p>
</div> </div>
</div> </div>
</div> </div>
@ -67,11 +67,10 @@
</div> </div>
<div class="circle-tile-content lightblue"> <div class="circle-tile-content lightblue">
<div class="circle-tile-description text-faded"> <div class="circle-tile-description text-faded">
<p class="h5 up" id="b-nextdiff">{if $GLOBAL.nethashrate > 0}{$NETWORK.EstNextDifficulty|number_format:"8"}{else}n/a{/if}</p> <p class="h5" id="b-nextdiff">{if $GLOBAL.nethashrate > 0}{$NETWORK.EstNextDifficulty|number_format:"8"}{else}n/a{/if}</p>
<p class="h6" id="b-nextdiffc">{if $GLOBAL.nethashrate > 0}Change in {$NETWORK.BlocksUntilDiffChange} Blocks{else}No Estimates{/if}</p>
</div> </div>
<div class="circle-tile-number text-faded"> <div class="circle-tile-number text-faded">
<p class="h6 up-more2">Est Next Difficulty</p> <p class="h6">Est Next Difficulty{if $GLOBAL.nethashrate > 0}<br/>Change in {$NETWORK.BlocksUntilDiffChange} Blocks{else}No Estimates{/if}</p>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,55 +1,154 @@
<div class="panel-footer"> <div class="panel-footer">
<div class="row text-center"> <div class="row text-center">
<div class="col-md-spark"> <div class="col-lg-2 col-sm-6">
<i class="fa fa-money fa-2x"></i> <div class="circle-tile fade">
<p id="b-payout" class="h5 font-bold m-t">{$GLOBAL.userdata.estimates.hours1|number_format:"12"}</p> <div class="circle-tile-heading lightblue">
<p class="h6 text-muted">{$GLOBAL.config.currency} 1 Hour Estimated Earnings</p> <i class="fa fa-money fa-fw fa-2x"></i>
</div>
<div class="circle-tile-content lightblue">
<div class="circle-tile-description text-faded">
<p class="h5" id="b-est1">{$GLOBAL.userdata.estimates.hours1|number_format:$PRECISION}</p>
</div>
<div class="circle-tile-number text-faded">
<p class="h6">{$GLOBAL.config.currency} 1 Hour Estimated Earnings</p>
</div>
</div>
</div>
</div> </div>
<div class="col-md-spark"> <div class="col-lg-2 col-sm-6">
<i class="fa fa-money fa-2x"></i> <div class="circle-tile fade">
<p id="b-payout" class="h6 font-bold m-t">{$GLOBAL.userdata.estimates.hours24|number_format:"12"}</p> <div class="circle-tile-heading lightblue">
<p class="h6 text-muted">{$GLOBAL.config.currency} 24 Hours Estimated Earnings</p> <i class="fa fa-money fa-fw fa-2x"></i>
</div>
<div class="circle-tile-content lightblue">
<div class="circle-tile-description text-faded">
<p class="h5" id="b-est24hours">{$GLOBAL.userdata.estimates.hours24|number_format:$PRECISION}</p>
</div>
<div class="circle-tile-number text-faded">
<p class="h6">{$GLOBAL.config.currency} 24 Hour Estimated Earnings</p>
</div>
</div>
</div>
</div> </div>
<div class="col-md-spark"> <div class="col-lg-2 col-sm-6">
<i class="fa fa-money fa-2x"></i> <div class="circle-tile fade">
<p id="b-payout" class="h5 font-bold m-t">{$GLOBAL.userdata.estimates.days7|number_format:"12"}</p> <div class="circle-tile-heading lightblue">
<p class="h6 text-muted">{$GLOBAL.config.currency} 7 Days Estimated Earnings</p> <i class="fa fa-money fa-fw fa-2x"></i>
</div>
<div class="circle-tile-content lightblue">
<div class="circle-tile-description text-faded">
<p class="h5" id="b-est7days">{$GLOBAL.userdata.estimates.days7|number_format:$PRECISION}</p>
</div>
<div class="circle-tile-number text-faded">
<p class="h6">{$GLOBAL.config.currency} 7 Days Estimated Earnings</p>
</div>
</div>
</div>
</div> </div>
<div class="col-md-spark"> <div class="col-lg-2 col-sm-6">
<i class="fa fa-money fa-2x"></i> <div class="circle-tile fade">
<p id="b-payout" class="h5 font-bold m-t">{$GLOBAL.userdata.estimates.days14|number_format:"12"}</p> <div class="circle-tile-heading lightblue">
<p class="h6 text-muted">{$GLOBAL.config.currency} 14 Days Estimated Earnings</p> <i class="fa fa-money fa-fw fa-2x"></i>
</div>
<div class="circle-tile-content lightblue">
<div class="circle-tile-description text-faded">
<p class="h5" id="b-est14days">{$GLOBAL.userdata.estimates.days14|number_format:$PRECISION}</p>
</div>
<div class="circle-tile-number text-faded">
<p class="h6">{$GLOBAL.config.currency} 14 Days Estimated Earnings</p>
</div>
</div>
</div>
</div> </div>
<div class="col-md-spark"> <div class="col-lg-2 col-sm-6">
<i class="fa fa-money fa-2x"></i> <div class="circle-tile fade">
<p id="b-payout" class="h5 font-bold m-t">{$GLOBAL.userdata.estimates.days30|number_format:"12"}</p> <div class="circle-tile-heading lightblue">
<p class="h6 text-muted">{$GLOBAL.config.currency} 30 Days Estimated Earnings</p> <i class="fa fa-money fa-fw fa-2x"></i>
</div>
<div class="circle-tile-content lightblue">
<div class="circle-tile-description text-faded">
<p class="h5" id="b-est30days">{$GLOBAL.userdata.estimates.days30|number_format:$PRECISION}</p>
</div>
<div class="circle-tile-number text-faded">
<p class="h6">{$GLOBAL.config.currency} 30 Days Estimated Earnings</p>
</div>
</div>
</div>
</div> </div>
<div class="col-md-spark"> <div class="col-lg-2 col-sm-6">
<i class="fa fa-th-large fa-2x"></i> <div class="circle-tile fade">
<p id="b-ppsvalue" class="h5 font-bold m-t">{$GLOBAL.ppsvalue}</p> <div class="circle-tile-heading lightblue">
<p class="h6 text-muted">PPS Value</p> <i class="fa fa-th-large fa-fw fa-2x"></i>
</div>
<div class="circle-tile-content lightblue">
<div class="circle-tile-description text-faded">
<p class="h5" id="b-ppsvalue">{$GLOBAL.ppsvalue}</p>
</div>
<div class="circle-tile-number text-faded">
<p class="h6">PPS<br/>Value</p>
</div>
</div>
</div>
</div> </div>
<div class="col-md-spark"> <div class="col-lg-2 col-sm-6">
<i class="fa fa-bar-chart-o fa-flip-horizontal fa-2x"></i> <div class="circle-tile fade">
<p id="b-unpaidshares" class="h6 font-bold m-t">{$GLOBAL.userdata.pps.unpaidshares}</p> <div class="circle-tile-heading lightblue">
<p class="h6 text-muted">Unpaid Shares</p> <i class="fa fa-bar-chart-o fa-fw fa-2x"></i>
</div>
<div class="circle-tile-content lightblue">
<div class="circle-tile-description text-faded">
<p class="h5" id="b-unpaidshares">{$GLOBAL.userdata.pps.unpaidshares}</p>
</div>
<div class="circle-tile-number text-faded">
<p class="h6">Unpaid<br/>difficulty shares</p>
</div>
</div>
</div>
</div> </div>
<div class="col-md-spark"> <div class="col-lg-2 col-sm-6">
<i class="fa fa-map-marker fa-2x"></i> <div class="circle-tile fade">
<p id="b-diff" class="h5 font-bold m-t">{$NETWORK.difficulty|number_format:"8"}</p> <div class="circle-tile-heading lightblue">
<p class="h6 text-muted">Difficulty</p> <i class="fa fa-map-marker fa-fw fa-2x"></i>
</div>
<div class="circle-tile-content lightblue">
<div class="circle-tile-description text-faded">
<p class="h5" id="b-diff">{$NETWORK.difficulty|number_format:"8"}</p>
</div>
<div class="circle-tile-number text-faded">
<p class="h6">Difficulty<br/>&nbsp;</p>
</div>
</div>
</div>
</div> </div>
<div class="col-md-spark"> <div class="col-lg-2 col-sm-6">
<i class="fa fa-sitemap fa-2x"></i> <div class="circle-tile fade">
<p id="b-nextdiff" class="h5 font-bold m-t">{if $GLOBAL.nethashrate > 0}{$NETWORK.EstNextDifficulty|number_format:"8"}{else}n/a{/if}</p> <div class="circle-tile-heading lightblue">
<p id="b-nextdiffc" class="h6 font-bold m-t">{if $GLOBAL.nethashrate > 0}Change in {$NETWORK.BlocksUntilDiffChange} Blocks{else}No Estimates{/if}</p> <i class="fa fa-sitemap fa-fw fa-2x"></i>
<p class="h6 text-muted">Est Next Difficulty</p> </div>
<div class="circle-tile-content lightblue">
<div class="circle-tile-description text-faded">
<p id="b-nextdiff" class="h5">{if $GLOBAL.nethashrate > 0}{$NETWORK.EstNextDifficulty|number_format:"8"}{else}n/a{/if}</p>
</div>
<div class="circle-tile-number text-faded">
<p class="h6">Est Next Difficulty{if $GLOBAL.nethashrate > 0}<br/>Change in {$NETWORK.BlocksUntilDiffChange} Blocks{else}No Estimates{/if}</p>
</div>
</div>
</div>
</div> </div>
<div class="col-md-spark"> <div class="col-lg-2 col-sm-6">
<i class="fa fa-clock-o fa-2x"></i> <div class="circle-tile fade">
<p id="b-esttimeperblock" class="h5 font-bold m-t">{$NETWORK.EstTimePerBlock|seconds_to_hhmmss}</p> <div class="circle-tile-heading lightblue">
<p class="h6 text-muted">Est. Avg. Time per Block</p> <i class="fa fa-clock-o fa-fw fa-2x"></i>
</div>
<div class="circle-tile-content lightblue">
<div class="circle-tile-description text-faded">
<p class="h5" id="b-esttimeperblock">{$NETWORK.EstTimePerBlock|seconds_to_hhmmss}</p>
</div>
<div class="circle-tile-number text-faded">
<p class="h6">Estimated Average<br/>Time per Block</p>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -37,10 +37,10 @@
</div> </div>
<div class="circle-tile-content lightblue"> <div class="circle-tile-content lightblue">
<div class="circle-tile-description text-faded"> <div class="circle-tile-description text-faded">
<p class="h5" id="b-payout">{$GLOBAL.userdata.estimates.payout|number_format:"8"}</p> <p class="h5" id="b-payout">{$GLOBAL.userdata.estimates.payout|number_format:$PRECISION}</p>
</div> </div>
<div class="circle-tile-number text-faded"> <div class="circle-tile-number text-faded">
<p class="h6">{$GLOBAL.config.currency} Est Earnings</p> <p class="h6">{$GLOBAL.config.currency} Est. Earnings</p>
</div> </div>
</div> </div>
</div> </div>
@ -67,11 +67,10 @@
</div> </div>
<div class="circle-tile-content lightblue"> <div class="circle-tile-content lightblue">
<div class="circle-tile-description text-faded"> <div class="circle-tile-description text-faded">
<p class="h5 up" id="b-nextdiff">{if $GLOBAL.nethashrate > 0}{$NETWORK.EstNextDifficulty|number_format:"8"}{else}n/a{/if}</p> <p class="h5" id="b-nextdiff">{if $GLOBAL.nethashrate > 0}{$NETWORK.EstNextDifficulty|number_format:"8"}{else}n/a{/if}</p>
<p class="h6" id="b-nextdiffc">{if $GLOBAL.nethashrate > 0}Change in {$NETWORK.BlocksUntilDiffChange} Blocks{else}No Estimates{/if}</p>
</div> </div>
<div class="circle-tile-number text-faded"> <div class="circle-tile-number text-faded">
<p class="h6">Est Next Difficulty</p> <p class="h6">Est Next Difficulty{if $GLOBAL.nethashrate > 0}<br/>Change in {$NETWORK.BlocksUntilDiffChange} Blocks{else}No Estimates{/if}</p>
</div> </div>
</div> </div>
</div> </div>

View File

@ -0,0 +1,30 @@
<?php
function run_0015() {
// Ugly but haven't found a better way
global $setting, $config, $user, $mysqli, $transaction;
// Version information
$db_version_old = '0.0.14'; // What version do we expect
$db_version_new = '0.0.15'; // What is the new version we wish to upgrade to
$db_version_now = $setting->getValue('DB_VERSION'); // Our actual version installed
// Upgrade specific variables
$aSql[] = "ALTER TABLE " . $transaction->getTableName() . " CHANGE `amount` `amount` DECIMAL(50,30) NULL DEFAULT '0'";
$aSql[] = "UPDATE " . $setting->getTableName() . " SET value = '0.0.15' WHERE name = 'DB_VERSION'";
if ($db_version_now == $db_version_old && version_compare($db_version_now, DB_VERSION, '<')) {
// Run the upgrade
echo '- Starting database migration to version ' . $db_version_new . PHP_EOL;
foreach ($aSql as $sql) {
echo '- Preparing: ' . $sql . PHP_EOL;
$stmt = $mysqli->prepare($sql);
if ($stmt && $stmt->execute()) {
echo '- success' . PHP_EOL;
} else {
echo '- failed: ' . $mysqli->error . PHP_EOL;
exit(1);
}
}
}
}
?>