From ee46e65fcae431da852240fb2a13e7f3f29b30e6 Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Sat, 26 Oct 2013 02:35:51 +0200 Subject: [PATCH 1/8] [FIX] Fixed potential PPLNS issue * getMinimumShareId did not use Share Counts but Weights --- public/include/classes/share.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/include/classes/share.class.php b/public/include/classes/share.class.php index 705c41e1..c8fcc989 100644 --- a/public/include/classes/share.class.php +++ b/public/include/classes/share.class.php @@ -326,7 +326,7 @@ class Share { $stmt = $this->mysqli->prepare(" SELECT MIN(b.id) AS id FROM ( - SELECT id, @total := @total + IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty) AS total + SELECT id, @total := @total + IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty) / POW(2, (" . $this->config['difficulty'] . " - 16)) AS total FROM $this->table, (SELECT @total := 0) AS a WHERE our_result = 'Y' AND id <= ? AND @total < ? From 0838bc77830941e25394da6ac71e7abd058060cf Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Sat, 26 Oct 2013 02:38:24 +0200 Subject: [PATCH 2/8] [FIX] Fixing PPS calculations * [FIX] PPS estimations * [FIX] PPS Value, PPS Payouts being off (too low) Tested on testnet, estimates worked perfectly and payouts worked well. --- cronjobs/pps_payout.php | 20 ++++++++++++-------- public/include/classes/statistics.class.php | 10 ++++------ public/include/config/global.inc.dist.php | 17 ++++++++++++++--- public/include/smarty_globals.inc.php | 2 +- 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/cronjobs/pps_payout.php b/cronjobs/pps_payout.php index 7c3515fb..58a72485 100755 --- a/cronjobs/pps_payout.php +++ b/cronjobs/pps_payout.php @@ -54,19 +54,18 @@ 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['pps_target']) * $dDifficulty), 12); +echo (pow(2, $config['pps_target']) * $dDifficulty); + // Find our last share accounted and last inserted share for PPS calculations $iPreviousShareId = $setting->getValue('pps_last_share_id'); @@ -75,11 +74,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 +98,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" . diff --git a/public/include/classes/statistics.class.php b/public/include/classes/statistics.class.php index 38f5360a..00e16066 100644 --- a/public/include/classes/statistics.class.php +++ b/public/include/classes/statistics.class.php @@ -645,14 +645,12 @@ 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; diff --git a/public/include/config/global.inc.dist.php b/public/include/config/global.inc.dist.php index b9cfda0d..734791fb 100644 --- a/public/include/config/global.inc.dist.php +++ b/public/include/config/global.inc.dist.php @@ -308,9 +308,20 @@ $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 +/** + * Please note: Do NOT touch this if you are running MPOS in scrypt coins! + * The VARDIFF / Stratum Settings / Target Bits system can be VERY confusing + * so unless you have spend over 2 hours talking with pooler, do not edit this. + * + * I have added this here to allow SHA256 coins in the future. For now, leave it + * at 16! + * + * Default: + * 16 = Scrypt + * Options: + * 32 = SHA256 + **/ +$config['pps_target'] = 16; /** * Memcache configuration diff --git a/public/include/smarty_globals.inc.php b/public/include/smarty_globals.inc.php index 9bb4ac60..da5916ec 100644 --- a/public/include/smarty_globals.inc.php +++ b/public/include/smarty_globals.inc.php @@ -140,7 +140,7 @@ if (@$_SESSION['USERDATA']['id']) { } } - $aGlobal['ppsvalue'] = number_format(round($pps_reward / (pow(2,32) * $dDifficulty) * pow(2, $config['pps_target']), 12) ,12); + $aGlobal['ppsvalue'] = number_format(round($pps_reward / (pow(2, $config['pps_target']) * $dDifficulty), 12) ,12); $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; From 3326ce092731c6f866452648de3ceee69dc14d30 Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Sat, 26 Oct 2013 09:48:07 +0200 Subject: [PATCH 3/8] [FIX] 14 and 30 days estimates --- public/include/classes/statistics.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/include/classes/statistics.class.php b/public/include/classes/statistics.class.php index 00e16066..2f48daf1 100644 --- a/public/include/classes/statistics.class.php +++ b/public/include/classes/statistics.class.php @@ -653,8 +653,8 @@ class Statistics { $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; From a6f9c25b5bf3049a1ddf992baf2c5d0c88d29b40 Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Sat, 26 Oct 2013 14:10:34 +0200 Subject: [PATCH 4/8] [UPDATE] Proper implementation of target bits * [ADDED] New Config Option: Algorithm * scrypt and sha256d supported right now * might add SHA coin support across MPOS * Compatible with previous implementation * [REMOVED] config option: pps_target * Replaced by config option: algorithm * Please update your config, defaults to srypt now! * [ADDED] Unpaid Shares in Dashboard * [MODIFIED] User estshares from DB query instead template math --- cronjobs/pps_payout.php | 3 +- public/include/autoloader.inc.php | 6 +++ public/include/classes/statistics.class.php | 46 ++++++++++++++----- public/include/config/global.inc.dist.php | 26 +++++------ .../pages/api/getdashboarddata.inc.php | 5 +- public/include/smarty_globals.inc.php | 3 +- public/templates/mpos/dashboard/js.tpl | 1 + .../templates/mpos/dashboard/system_stats.tpl | 4 ++ .../mpos/statistics/blocks/default.tpl | 7 ++- 9 files changed, 65 insertions(+), 36 deletions(-) diff --git a/cronjobs/pps_payout.php b/cronjobs/pps_payout.php index 58a72485..ca0a8c3c 100755 --- a/cronjobs/pps_payout.php +++ b/cronjobs/pps_payout.php @@ -63,8 +63,7 @@ if ($config['pps']['reward']['type'] == 'blockavg' && $block->getBlockCount() > } // Per-share value to be paid out to users -$pps_value = round($pps_reward / (pow(2, $config['pps_target']) * $dDifficulty), 12); -echo (pow(2, $config['pps_target']) * $dDifficulty); +$pps_value = round($pps_reward / (pow(2, $config['target_bits']) * $dDifficulty), 12); // Find our last share accounted and last inserted share for PPS calculations diff --git a/public/include/autoloader.inc.php b/public/include/autoloader.inc.php index 8950f103..b393387e 100644 --- a/public/include/autoloader.inc.php +++ b/public/include/autoloader.inc.php @@ -1,5 +1,11 @@ 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 diff --git a/public/include/config/global.inc.dist.php b/public/include/config/global.inc.dist.php index 734791fb..1609b8b8 100644 --- a/public/include/config/global.inc.dist.php +++ b/public/include/config/global.inc.dist.php @@ -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,21 +319,6 @@ $config['pps']['reward']['default'] = 50; $config['pps']['reward']['type'] = 'blockavg'; $config['pps']['blockavg']['blockcount'] = 10; -/** - * Please note: Do NOT touch this if you are running MPOS in scrypt coins! - * The VARDIFF / Stratum Settings / Target Bits system can be VERY confusing - * so unless you have spend over 2 hours talking with pooler, do not edit this. - * - * I have added this here to allow SHA256 coins in the future. For now, leave it - * at 16! - * - * Default: - * 16 = Scrypt - * Options: - * 32 = SHA256 - **/ -$config['pps_target'] = 16; - /** * Memcache configuration * diff --git a/public/include/pages/api/getdashboarddata.inc.php b/public/include/pages/api/getdashboarddata.inc.php index 4d15763d..747beb04 100644 --- a/public/include/pages/api/getdashboarddata.inc.php +++ b/public/include/pages/api/getdashboarddata.inc.php @@ -42,6 +42,7 @@ $aRoundShares = $statistics->getRoundShares(); if ($config['payout_system'] != 'pps') { $aEstimates = $statistics->getUserEstimates($aRoundShares, $aUserRoundShares, $user->getUserDonatePercent($user_id), $user->getUserNoFee($user_id)); } 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 +57,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 +90,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, diff --git a/public/include/smarty_globals.inc.php b/public/include/smarty_globals.inc.php index da5916ec..3fb1faf5 100644 --- a/public/include/smarty_globals.inc.php +++ b/public/include/smarty_globals.inc.php @@ -140,7 +140,8 @@ if (@$_SESSION['USERDATA']['id']) { } } - $aGlobal['ppsvalue'] = number_format(round($pps_reward / (pow(2, $config['pps_target']) * $dDifficulty), 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['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; diff --git a/public/templates/mpos/dashboard/js.tpl b/public/templates/mpos/dashboard/js.tpl index f8c53fe3..fb72d04f 100644 --- a/public/templates/mpos/dashboard/js.tpl +++ b/public/templates/mpos/dashboard/js.tpl @@ -156,6 +156,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))); diff --git a/public/templates/mpos/dashboard/system_stats.tpl b/public/templates/mpos/dashboard/system_stats.tpl index 04a97692..300483ba 100644 --- a/public/templates/mpos/dashboard/system_stats.tpl +++ b/public/templates/mpos/dashboard/system_stats.tpl @@ -9,6 +9,10 @@ {elseif $GLOBAL.config.payout_system == 'pps'} + + Unpaid Shares + {$GLOBAL.userdata.pps.unpaidshares} + PPS Value {$GLOBAL.ppsvalue} diff --git a/public/templates/mpos/statistics/blocks/default.tpl b/public/templates/mpos/statistics/blocks/default.tpl index e3a770a1..c2587a12 100644 --- a/public/templates/mpos/statistics/blocks/default.tpl +++ b/public/templates/mpos/statistics/blocks/default.tpl @@ -103,14 +103,13 @@ {$BLOCKSFOUND[block].difficulty|number_format:"2"} {$BLOCKSFOUND[block].amount|number_format:"2"} -{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} {if $GLOBAL.config.payout_system == 'pplns'}{$BLOCKSFOUND[block].pplns_shares|number_format}{/if} {$BLOCKSFOUND[block].shares|number_format} -{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} {$percentage|number_format:"2"} From 3a0e2a9a13df8c6a00986f14b706000d3d29230e Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Sun, 27 Oct 2013 02:45:43 +0100 Subject: [PATCH 5/8] [FIX] Dashboard API on non-PPS system --- public/include/pages/api/getdashboarddata.inc.php | 1 + 1 file changed, 1 insertion(+) diff --git a/public/include/pages/api/getdashboarddata.inc.php b/public/include/pages/api/getdashboarddata.inc.php index 747beb04..f4e48fbd 100644 --- a/public/include/pages/api/getdashboarddata.inc.php +++ b/public/include/pages/api/getdashboarddata.inc.php @@ -41,6 +41,7 @@ $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) { From 20a9fc3e289d0f41cdc4edbecf544260b863b6eb Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Sun, 27 Oct 2013 02:51:03 +0100 Subject: [PATCH 6/8] Revert "[FIX] Fixed potential PPLNS issue" This reverts commit ee46e65fcae431da852240fb2a13e7f3f29b30e6. --- public/include/classes/share.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/include/classes/share.class.php b/public/include/classes/share.class.php index c8fcc989..705c41e1 100644 --- a/public/include/classes/share.class.php +++ b/public/include/classes/share.class.php @@ -326,7 +326,7 @@ class Share { $stmt = $this->mysqli->prepare(" SELECT MIN(b.id) AS id FROM ( - SELECT id, @total := @total + IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty) / POW(2, (" . $this->config['difficulty'] . " - 16)) AS total + SELECT id, @total := @total + IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty) AS total FROM $this->table, (SELECT @total := 0) AS a WHERE our_result = 'Y' AND id <= ? AND @total < ? From a2472284a896e680b6b86a8b74fff89bfcb475a1 Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Sun, 27 Oct 2013 03:28:41 +0100 Subject: [PATCH 7/8] [FIX] Proper fetch Archive Shares Is now in-line with getMininumShareId. --- cronjobs/pplns_payout.php | 2 +- public/include/classes/share.class.php | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/cronjobs/pplns_payout.php b/cronjobs/pplns_payout.php index 15e8d6b4..1fe17879 100755 --- a/cronjobs/pplns_payout.php +++ b/cronjobs/pplns_payout.php @@ -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"); diff --git a/public/include/classes/share.class.php b/public/include/classes/share.class.php index 705c41e1..d31827ef 100644 --- a/public/include/classes/share.class.php +++ b/public/include/classes/share.class.php @@ -343,10 +343,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,6 +358,7 @@ 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; } From 8f51faf963277ea79bf66d10dd4d49ed65e67e1c Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Mon, 28 Oct 2013 13:16:17 +0100 Subject: [PATCH 8/8] [IMPROVED] Adding pools specific PPS rate * Show Diff1 Baseline PPS Rate * Use pools set minimum difficulty to display pool based rate --- public/include/smarty_globals.inc.php | 1 + public/templates/mpos/dashboard/system_stats.tpl | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/public/include/smarty_globals.inc.php b/public/include/smarty_globals.inc.php index 3fb1faf5..5f2c691e 100644 --- a/public/include/smarty_globals.inc.php +++ b/public/include/smarty_globals.inc.php @@ -142,6 +142,7 @@ if (@$_SESSION['USERDATA']['id']) { $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; diff --git a/public/templates/mpos/dashboard/system_stats.tpl b/public/templates/mpos/dashboard/system_stats.tpl index 300483ba..46b12f12 100644 --- a/public/templates/mpos/dashboard/system_stats.tpl +++ b/public/templates/mpos/dashboard/system_stats.tpl @@ -14,8 +14,12 @@ {$GLOBAL.userdata.pps.unpaidshares} - PPS Value - {$GLOBAL.ppsvalue} + Baseline PPS Rate + {$GLOBAL.ppsvalue} {$GLOBAL.config.currency} + + + Pools PPS Rate + {$GLOBAL.poolppsvalue} {$GLOBAL.config.currency} PPS Difficulty