From 0addd6ec806f3db0b65dee2ec7b531f627bd59ac Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Fri, 25 Oct 2013 09:31:25 +0200 Subject: [PATCH] [IMPROVED] User payout estimations * [ADDED] Proper PPS caclulations to statistics getUserEstimates * [IMPROVED] Updated themes to use new estimates format in global smarty * [IMPROVED] Updated PPS Dashboard to update estimates via Ajax * [IMPROVED] Added PPS estimates to getdashboarddata API This will require theme updates for those sites relying on the est_ format for user payout estimates! Fixes #743 once merged. --- public/include/classes/statistics.class.php | 67 +++++++++++++++---- .../pages/api/getdashboarddata.inc.php | 25 ++++++- public/include/smarty_globals.inc.php | 47 ++++++------- .../templates/mmcFE/global/sidebar_pplns.tpl | 8 +-- public/templates/mmcFE/global/sidebar_pps.tpl | 14 +++- .../templates/mmcFE/global/sidebar_prop.tpl | 8 +-- .../templates/mobile/global/sidebar_pplns.tpl | 8 +-- .../templates/mobile/global/sidebar_pps.tpl | 6 +- .../templates/mobile/global/sidebar_prop.tpl | 8 +-- .../templates/mpos/dashboard/default_pps.tpl | 32 ++++++--- public/templates/mpos/dashboard/js.tpl | 11 +++ 11 files changed, 164 insertions(+), 70 deletions(-) diff --git a/public/include/classes/statistics.class.php b/public/include/classes/statistics.class.php index d3b87ada..d7367248 100644 --- a/public/include/classes/statistics.class.php +++ b/public/include/classes/statistics.class.php @@ -326,6 +326,24 @@ class Statistics { return false; } + + 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; + $stmt = $this->mysqli->prepare(" + SELECT + AVG(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) AS avgsharediff, + COUNT(s.id) AS total + FROM " . $this->share->getTableName() . " AS s JOIN " . $this->user->getTableName() . " AS a + ON a.username = SUBSTRING_INDEX( s.username, '.', 1 ) + WHERE s.time > DATE_SUB(now(), INTERVAL ? SECOND) + AND a.id = ?"); + if ($this->checkStmt($stmt) && $stmt->bind_param("ii", $interval, $account_id) && $stmt->execute() && $result = $stmt->get_result() ) + return $this->memcache->setCache(__FUNCTION__ . $account_id, $result->fetch_object()->avgsharediff); + $this->debug->append("Failed fetching average share dificulty: " . $this->mysqli->error, 3); + return 0; + } + /** * Same as getUserHashrate for Sharerate * @param account_id integer User ID @@ -539,28 +557,51 @@ class Statistics { /** * get user estimated payouts based on share counts - * @param aRoundShares array Round shares - * @param aUserShares array User shares + * @param value1 mixed Round shares OR share rate + * @param value2 mixed User shares OR share difficulty * @param dDonate double User donation setting * @param bNoFees bool User no-fees option setting * @return aEstimates array User estimations **/ - public function getUserEstimates($aRoundShares, $aUserShares, $dDonate, $bNoFees) { + public function getUserEstimates($value1, $value2, $dDonate, $bNoFees, $ppsvalue=0) { $this->debug->append("STA " . __METHOD__, 4); - // Fetch some user information that we need - if (@$aRoundShares['valid'] > 0 && @$aUserShares['valid'] > 0) { - $aEstimates['block'] = round(( (int)$aUserShares['valid'] / (int)$aRoundShares['valid'] ) * (float)$this->config['reward'], 8); - $bNoFees == 0 ? $aEstimates['fee'] = round(((float)$this->config['fees'] / 100) * (float)$aEstimates['block'], 8) : $aEstimates['fee'] = 0; - $aEstimates['donation'] = round((( (float)$dDonate / 100) * ((float)$aEstimates['block'] - (float)$aEstimates['fee'])), 8); - $aEstimates['payout'] = round((float)$aEstimates['block'] - (float)$aEstimates['donation'] - (float)$aEstimates['fee'], 8); + if ($this->config['payout_system'] != 'pps') { + if (@$value1['valid'] > 0 && @$value2['valid'] > 0) { + $aEstimates['block'] = round(( (int)$value2['valid'] / (int)$value1['valid'] ) * (float)$this->config['reward'], 8); + $bNoFees == 0 ? $aEstimates['fee'] = round(((float)$this->config['fees'] / 100) * (float)$aEstimates['block'], 8) : $aEstimates['fee'] = 0; + $aEstimates['donation'] = round((( (float)$dDonate / 100) * ((float)$aEstimates['block'] - (float)$aEstimates['fee'])), 8); + $aEstimates['payout'] = round((float)$aEstimates['block'] - (float)$aEstimates['donation'] - (float)$aEstimates['fee'], 8); + } else { + $aEstimates['block'] = 0; + $aEstimates['fee'] = 0; + $aEstimates['donation'] = 0; + $aEstimates['payout'] = 0; + } } else { - $aEstimates['block'] = 0; - $aEstimates['fee'] = 0; - $aEstimates['donation'] = 0; - $aEstimates['payout'] = 0; + // Hack so we can use this method for PPS estimates too + 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; + $pps = $value1 * $value2 * $ppsvalue; + $hour = 3600; + $aEstimates['hours1'] = $pps * $hour * $fee; + $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; + } else { + $aEstimates['hours1'] = 0; + $aEstimates['hours24'] = 0; + $aEstimates['days7'] = 0; + $aEstimates['days14'] = 0; + $aEstimates['days30'] = 0; + } } return $aEstimates; } } + $statistics = new Statistics($debug, $mysqli, $config, $share, $user, $block, $memcache); diff --git a/public/include/pages/api/getdashboarddata.inc.php b/public/include/pages/api/getdashboarddata.inc.php index 9aa2adfd..8cf263f5 100644 --- a/public/include/pages/api/getdashboarddata.inc.php +++ b/public/include/pages/api/getdashboarddata.inc.php @@ -32,12 +32,33 @@ $dPoolHashrate = $statistics->getCurrentHashrate($interval); if ($dPoolHashrate > $dNetworkHashrate) $dNetworkHashrate = $dPoolHashrate; $dPersonalHashrate = $statistics->getUserHashrate($user_id, $interval); $dPersonalSharerate = $statistics->getUserSharerate($user_id, $interval); +$dPersonalShareDifficulty = $statistics->getUserShareDifficulty($user_id, $interval); $statistics->setGetCache(true); // Use caches for this one $aUserRoundShares = $statistics->getUserShares($user_id); $aRoundShares = $statistics->getRoundShares(); -$aEstimates = $statistics->getUserEstimates($aRoundShares, $aUserRoundShares, $user->getUserDonatePercent($user_id), $user->getUserNoFee($user_id)); + +if ($config['payout_system'] != 'pps') { + $aEstimates = $statistics->getUserEstimates($aRoundShares, $aUserRoundShares, $user->getUserDonatePercent($user_id), $user->getUserNoFee($user_id)); +} else { + if ($config['pps']['reward']['type'] == 'blockavg' && $block->getBlockCount() > 0) { + $pps_reward = round($block->getAvgBlockReward($config['pps']['blockavg']['blockcount'])); + } else { + if ($config['pps']['reward']['type'] == 'block') { + if ($aLastBlock = $block->getLast()) { + $pps_reward = $aLastBlock['amount']; + } else { + $pps_reward = $config['pps']['reward']['default']; + } + } else { + $pps_reward = $config['pps']['reward']['default']; + } + } + + $ppsvalue = round($pps_reward / (pow(2,32) * $dDifficulty) * pow(2, $config['pps_target']), 12); + $aEstimates = $statistics->getUserEstimates($dPersonalSharerate, $dPersonalShareDifficulty, $user->getUserDonatePercent($user_id), $user->getUserNoFee($user_id), $ppsvalue); +} // Apply pool modifiers $dPersonalHashrateAdjusted = $dPersonalHashrate * $dPersonalHashrateModifier; @@ -54,7 +75,7 @@ $aPrice = $setting->getValue('price'); $data = array( 'raw' => array( 'personal' => array( 'hashrate' => $dPersonalHashrate ), 'pool' => array( 'hashrate' => $dPoolHashrate ), 'network' => array( 'hashrate' => $dNetworkHashrate / 1000 ) ), 'personal' => array ( - 'hashrate' => $dPersonalHashrateAdjusted, 'sharerate' => $dPersonalSharerate, + 'hashrate' => $dPersonalHashrateAdjusted, 'sharerate' => $dPersonalSharerate, 'sharedifficulty' => $dPersonalShareDifficulty, 'shares' => array('valid' => $aUserRoundShares['valid'], 'invalid' => $aUserRoundShares['invalid']), 'balance' => $transaction->getBalance($user_id), 'estimates' => $aEstimates, 'workers' => $aWorkers ), 'pool' => array( 'workers' => $worker->getCountAllActiveWorkers(), 'hashrate' => $dPoolHashrateAdjusted, 'shares' => $aRoundShares, 'price' => $aPrice ), diff --git a/public/include/smarty_globals.inc.php b/public/include/smarty_globals.inc.php index 8beb33b0..9bb4ac60 100644 --- a/public/include/smarty_globals.inc.php +++ b/public/include/smarty_globals.inc.php @@ -97,24 +97,6 @@ $aGlobal['acl']['pool']['statistics'] = $setting->getValue('acl_pool_statistics' $aGlobal['acl']['block']['statistics'] = $setting->getValue('acl_block_statistics'); $aGlobal['acl']['round']['statistics'] = $setting->getValue('acl_round_statistics'); -// We support some dynamic reward targets but fall back to our fixed value -// Special calculations for PPS Values based on reward_type setting and/or available blocks -if ($config['pps']['reward']['type'] == 'blockavg' && $block->getBlockCount() > 0) { - $pps_reward = round($block->getAvgBlockReward($config['pps']['blockavg']['blockcount'])); -} else { - if ($config['pps']['reward']['type'] == 'block') { - if ($aLastBlock = $block->getLast()) { - $pps_reward = $aLastBlock['amount']; - } else { - $pps_reward = $config['pps']['reward']['default']; - } - } else { - $pps_reward = $config['pps']['reward']['default']; - } -} - -$aGlobal['ppsvalue'] = number_format(round($pps_reward / (pow(2,32) * $dDifficulty) * pow(2, $config['pps_target']), 12) ,12); - // We don't want these session infos cached if (@$_SESSION['USERDATA']['id']) { $aGlobal['userdata'] = $_SESSION['USERDATA']['id'] ? $user->getUserData($_SESSION['USERDATA']['id']) : array(); @@ -126,13 +108,11 @@ if (@$_SESSION['USERDATA']['id']) { $aGlobal['userdata']['sharerate'] = $statistics->getUserSharerate($_SESSION['USERDATA']['id']); switch ($config['payout_system']) { - case 'prop' || 'pplns': + case 'prop': // Some estimations $aEstimates = $statistics->getUserEstimates($aRoundShares, $aGlobal['userdata']['shares'], $aGlobal['userdata']['donate_percent'], $aGlobal['userdata']['no_fees']); - $aGlobal['userdata']['est_block'] = $aEstimates['block']; - $aGlobal['userdata']['est_fee'] = $aEstimates['fee']; - $aGlobal['userdata']['est_donation'] = $aEstimates['donation']; - $aGlobal['userdata']['est_payout'] = $aEstimates['payout']; + $aGlobal['userdata']['estimates'] = $aEstimates; + break; case 'pplns': $aGlobal['pplns']['target'] = $config['pplns']['shares']['default']; if ($aLastBlock = $block->getLast()) { @@ -140,8 +120,29 @@ if (@$_SESSION['USERDATA']['id']) { $aGlobal['pplns']['target'] = $iAvgBlockShares; } } + $aEstimates = $statistics->getUserEstimates($aRoundShares, $aGlobal['userdata']['shares'], $aGlobal['userdata']['donate_percent'], $aGlobal['userdata']['no_fees']); + $aGlobal['userdata']['estimates'] = $aEstimates; break; case 'pps': + // We support some dynamic reward targets but fall back to our fixed value + // Special calculations for PPS Values based on reward_type setting and/or available blocks + if ($config['pps']['reward']['type'] == 'blockavg' && $block->getBlockCount() > 0) { + $pps_reward = round($block->getAvgBlockReward($config['pps']['blockavg']['blockcount'])); + } else { + if ($config['pps']['reward']['type'] == 'block') { + if ($aLastBlock = $block->getLast()) { + $pps_reward = $aLastBlock['amount']; + } else { + $pps_reward = $config['pps']['reward']['default']; + } + } else { + $pps_reward = $config['pps']['reward']['default']; + } + } + + $aGlobal['ppsvalue'] = number_format(round($pps_reward / (pow(2,32) * $dDifficulty) * pow(2, $config['pps_target']), 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/mmcFE/global/sidebar_pplns.tpl b/public/templates/mmcFE/global/sidebar_pplns.tpl index 138b40c5..4923519b 100644 --- a/public/templates/mmcFE/global/sidebar_pplns.tpl +++ b/public/templates/mmcFE/global/sidebar_pplns.tpl @@ -53,19 +53,19 @@ Block - {$GLOBAL.userdata.est_block|number_format:"3"} + {$GLOBAL.userdata.estimates.block|number_format:"3"} Fees - {$GLOBAL.userdata.est_fee|number_format:"3"} + {$GLOBAL.userdata.estimates.fee|number_format:"3"} Donation - {$GLOBAL.userdata.est_donation|number_format:"3"} + {$GLOBAL.userdata.estimates.donation|number_format:"3"} Payout - {$GLOBAL.userdata.est_payout|number_format:"3"} + {$GLOBAL.userdata.estimates.payout|number_format:"3"}   {$GLOBAL.config.currency} Account Balance diff --git a/public/templates/mmcFE/global/sidebar_pps.tpl b/public/templates/mmcFE/global/sidebar_pps.tpl index 2759fc27..19535adb 100644 --- a/public/templates/mmcFE/global/sidebar_pps.tpl +++ b/public/templates/mmcFE/global/sidebar_pps.tpl @@ -42,17 +42,25 @@   {$GLOBAL.config.currency} Estimates + + in 1 hour + {$GLOBAL.userdata.estimates.hours1|round:"8"} + in 24 hours - {($GLOBAL.userdata.sharerate * 24 * 60 * 60 * $GLOBAL.ppsvalue)|number_format:"8"} + {$GLOBAL.userdata.estimates.hours24|round:"8"} in 7 days - {($GLOBAL.userdata.sharerate * 7 * 24 * 60 * 60 * $GLOBAL.ppsvalue)|number_format:"8"} + {$GLOBAL.userdata.estimates.days7|round:"8"} in 14 days - {($GLOBAL.userdata.sharerate * 14 * 24 * 60 * 60 * $GLOBAL.ppsvalue)|number_format:"8"} + {$GLOBAL.userdata.estimates.days14|round:"8"} + + + in 30 days + {$GLOBAL.userdata.estimates.days30|round:"8"}   {$GLOBAL.config.currency} Account Balance diff --git a/public/templates/mmcFE/global/sidebar_prop.tpl b/public/templates/mmcFE/global/sidebar_prop.tpl index 8c9d5e0a..d5ec7fc0 100644 --- a/public/templates/mmcFE/global/sidebar_prop.tpl +++ b/public/templates/mmcFE/global/sidebar_prop.tpl @@ -48,19 +48,19 @@ Block - {$GLOBAL.userdata.est_block|number_format:"8"} + {$GLOBAL.userdata.estimates.block|number_format:"8"} Fees - {$GLOBAL.userdata.est_fee|number_format:"8"} + {$GLOBAL.userdata.estimates.fee|number_format:"8"} Donation - {$GLOBAL.userdata.est_donation|number_format:"8"} + {$GLOBAL.userdata.estimates.donation|number_format:"8"} Payout - {$GLOBAL.userdata.est_payout|number_format:"8"} + {$GLOBAL.userdata.estimates.payout|number_format:"8"}   {$GLOBAL.config.currency} Account Balance diff --git a/public/templates/mobile/global/sidebar_pplns.tpl b/public/templates/mobile/global/sidebar_pplns.tpl index a7c5fa02..7c25728b 100644 --- a/public/templates/mobile/global/sidebar_pplns.tpl +++ b/public/templates/mobile/global/sidebar_pplns.tpl @@ -46,19 +46,19 @@ Block - {$GLOBAL.userdata.est_block|number_format:"3"} + {$GLOBAL.userdata.estimates.block|number_format:"3"} Fees - {$GLOBAL.userdata.est_fee|number_format:"3"} + {$GLOBAL.userdata.estimates.fee|number_format:"3"} Donation - {$GLOBAL.userdata.est_donation|number_format:"3"} + {$GLOBAL.userdata.estimates.donation|number_format:"3"} Payout - {$GLOBAL.userdata.est_payout|number_format:"3"} + {$GLOBAL.userdata.estimates.payout|number_format:"3"}   {$GLOBAL.config.currency} Account Balance diff --git a/public/templates/mobile/global/sidebar_pps.tpl b/public/templates/mobile/global/sidebar_pps.tpl index e76614dc..71ada55c 100644 --- a/public/templates/mobile/global/sidebar_pps.tpl +++ b/public/templates/mobile/global/sidebar_pps.tpl @@ -35,15 +35,15 @@ {$GLOBAL.config.currency} Estimates in 24 hours - {($GLOBAL.userdata.sharerate * 24 * 60 * 60 * $GLOBAL.ppsvalue)|number_format:"8"} + {$GLOBAL.userdata.estimates.hours24} in 7 days - {($GLOBAL.userdata.sharerate * 7 * 24 * 60 * 60 * $GLOBAL.ppsvalue)|number_format:"8"} + {$GLOBAL.userdata.estimates.days7} in 14 days - {($GLOBAL.userdata.sharerate * 14 * 24 * 60 * 60 * $GLOBAL.ppsvalue)|number_format:"8"} + {$GLOBAL.userdata.estimates.days14}   {$GLOBAL.config.currency} Account Balance diff --git a/public/templates/mobile/global/sidebar_prop.tpl b/public/templates/mobile/global/sidebar_prop.tpl index 858740bc..5ab614a2 100644 --- a/public/templates/mobile/global/sidebar_prop.tpl +++ b/public/templates/mobile/global/sidebar_prop.tpl @@ -38,19 +38,19 @@ Block - {$GLOBAL.userdata.est_block|number_format:"8"} + {$GLOBAL.userdata.estimates.block|number_format:"8"} Fees - {$GLOBAL.userdata.est_fee|number_format:"8"} + {$GLOBAL.userdata.estimates.fee|number_format:"8"} Donation - {$GLOBAL.userdata.est_donation|number_format:"8"} + {$GLOBAL.userdata.estimates.donation|number_format:"8"} Payout - {$GLOBAL.userdata.est_payout|number_format:"8"} + {$GLOBAL.userdata.estimates.payout|number_format:"8"}   {$GLOBAL.config.currency} Account Balance diff --git a/public/templates/mpos/dashboard/default_pps.tpl b/public/templates/mpos/dashboard/default_pps.tpl index cc083753..f1d415ff 100644 --- a/public/templates/mpos/dashboard/default_pps.tpl +++ b/public/templates/mpos/dashboard/default_pps.tpl @@ -7,39 +7,51 @@ PPS Value {$GLOBAL.ppsvalue} -   + + PPS Difficulty + {$GLOBAL.userdata.sharedifficulty|number_format:"2"} + +   Round Shares Pool Valid - + Your Valid - + Pool Invalid - + Your Invalid - +   {$GLOBAL.config.currency} Estimates + + in 1 hour + {$GLOBAL.userdata.estimates.hours1|round:"8"} + in 24 hours - {($GLOBAL.userdata.sharerate * 24 * 60 * 60 * $GLOBAL.ppsvalue)|number_format:"8"} + {($GLOBAL.userdata.estimates.hours24)|round:"8"} in 7 days - {($GLOBAL.userdata.sharerate * 7 * 24 * 60 * 60 * $GLOBAL.ppsvalue)|number_format:"8"} + {($GLOBAL.userdata.estimates.days7)|round:"8"} in 14 days - {($GLOBAL.userdata.sharerate * 14 * 24 * 60 * 60 * $GLOBAL.ppsvalue)|number_format:"8"} + {($GLOBAL.userdata.estimates.days14)|round:"8"} + + + in 30 days + {($GLOBAL.userdata.estimates.days30)|round:"8"}   @@ -47,11 +59,11 @@ Current Difficulty - + Current Block - +   diff --git a/public/templates/mpos/dashboard/js.tpl b/public/templates/mpos/dashboard/js.tpl index a19032d7..37fc6d3e 100644 --- a/public/templates/mpos/dashboard/js.tpl +++ b/public/templates/mpos/dashboard/js.tpl @@ -150,11 +150,22 @@ $(document).ready(function(){ $('#b-pivalid').html(data.getdashboarddata.data.pool.shares.invalid); $('#b-diff').html(data.getdashboarddata.data.network.difficulty); $('#b-nblock').html(data.getdashboarddata.data.network.block); + {/literal}{if $GLOBAL.config.payout_system != 'pps'}{literal } $('#b-payout').html((parseFloat(data.getdashboarddata.data.personal.estimates.payout).toFixed(4))); $('#b-block').html((parseFloat(data.getdashboarddata.data.personal.estimates.block).toFixed(4))); $('#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-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))); + $('#b-est7days').html((parseFloat(data.getdashboarddata.data.personal.estimates.days7).toFixed(8))); + $('#b-est14days').html((parseFloat(data.getdashboarddata.data.personal.estimates.days14).toFixed(8))); + $('#b-est30days').html((parseFloat(data.getdashboarddata.data.personal.estimates.days30).toFixed(8))); +{/literal}{/if}{literal} +{/literal}{if $GLOBAL.config.payout_system == 'pplns'}{literal} $('#b-pplns').html({/literal}{$GLOBAL.pplns.target}{literal}); +{/literal}{/if}{literal} } // Refresh worker information