[ADDED] Coin Precision Setting

* [UPDATED] Cronjobs to store real values, display with coin precision
* [UPDATED] Templates to use new coin precision setting in dashboard
* [UPDATED] JS API calls to use new precision setting too
* [UPDATED] PPS Value is displayed as coin precision + 8

This should help with #2216 and address issues with coins where rounding
of 12 was not enough.
This commit is contained in:
Sebastian Grewe 2014-06-30 07:59:42 +02:00
parent a9bfc91e7a
commit 4f8e9c505f
10 changed files with 190 additions and 77 deletions

View File

@ -38,6 +38,9 @@ if (empty($aAllBlocks)) {
$monitoring->endCronjob($cron_name, 'E0011', 0, true, false);
}
// Fetch precision
$precision = $setting->getValue('system_coin_precision', 12);
$log->logDebug('Starting PPLNS payout process');
$count = 0;
foreach ($aAllBlocks as $iIndex => $aBlock) {

View File

@ -63,7 +63,7 @@ if ($config['pps']['reward']['type'] == 'blockavg' && $block->getBlockCount() >
}
// 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
if (!$iPreviousShareId = $setting->getValue('pps_last_share_id')) {
@ -89,10 +89,11 @@ $log->logInfo("\tQuery Completed...");
if (!empty($aAccountShares)) {
// Runtime information for this payout
$precision = $setting->getValue('system_coin_precision', 12);
$log->logInfo('Runtime information for this payout');
$strLogMask = "| %-15.15s | %15.15s | %15.15s | %15.15s |";
$log->logInfo(sprintf($strLogMask, 'PPS reward type', 'Reward Base', 'Difficulty', 'PPS Value'));
$log->logInfo(sprintf($strLogMask, $strRewardType, $pps_reward, $dDifficulty, $pps_value));
$strLogMask = "| %-15.15s | %15.15s | %15.15s | %15.15s | %3.3s |";
$log->logInfo(sprintf($strLogMask, 'PPS reward type', 'Reward Base', 'Difficulty', 'PPS Value', 'Precision'));
$log->logInfo(sprintf($strLogMask, $strRewardType, $pps_reward, $dDifficulty, $pps_value, $precision));
$log->logInfo('Per-user payout information');
$strLogMask = "| %8.8s | %25.25s | %15.15s | %15.15s | %18.18s | %18.18s | %18.18s |";
$log->logInfo(sprintf($strLogMask, 'User ID', 'Username', 'Invalid', 'Valid', ' * PPS Value', ' = Payout', 'Donation', 'Fee'));
@ -106,7 +107,7 @@ foreach ($aAccountShares as $aData) {
}
// Payout for this user
$aData['payout'] = round($aData['valid'] * $pps_value, 12);
$aData['payout'] = $aData['valid'] * $pps_value;
// Defaults
$aData['fee' ] = 0;
@ -114,13 +115,13 @@ foreach ($aAccountShares as $aData) {
// Calculate block fees
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
$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(
$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

View File

@ -38,6 +38,9 @@ if (empty($aAllBlocks)) {
$monitoring->endCronjob($cron_name, 'E0011', 0, true, false);
}
// Fetch precision
$precision = $setting->getValue('system_coin_precision', 12);
$count = 0;
// 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 |";
@ -87,29 +90,29 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
$aData['fee' ] = 0;
$aData['donation'] = 0;
$aData['pool_bonus'] = 0;
$aData['percentage'] = round(( 100 / $iRoundShares ) * $aData['valid'], 8);
$aData['payout'] = round(( $aData['percentage'] / 100 ) * $dReward, 8);
$aData['percentage'] = ( 100 / $iRoundShares ) * $aData['valid'];
$aData['payout'] = ( $aData['percentage'] / 100 ) * $dReward;
// Calculate pool fees if they apply
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!
if ($config['pool_bonus'] > 0) {
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 {
$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
$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
$log->logInfo(
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

View File

@ -308,9 +308,16 @@ $aSettings['system'][] = array(
'name' => 'system_error_email', 'value' => $setting->getValue('system_error_email'),
'tooltip' => 'The email address for system errors notifications, like cronjobs failures.'
);
$aSettings['system'][] = array(
'display' => 'Coin Precision', 'type' => 'text',
'size' => 5,
'default' => '12',
'name' => 'system_coin_precision', 'value' => $setting->getValue('system_coin_precision'),
'tooltip' => 'How do we round any coin values throughout MPOS. Defaults to 12 digits.'
);
$aSettings['system'][] = array(
'display' => 'Date format string', 'type' => 'text',
'site' => 25,
'size' => 25,
'default' => '%m/%d/%Y %H:%M:%S',
'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.'

View File

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

View File

@ -175,7 +175,8 @@ if (@$_SESSION['USERDATA']['id']) {
break;
case 'pps':
$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(), $setting->getValue('system_coin_precision', 12) + 8);
$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']);
break;

View File

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

View File

@ -37,10 +37,10 @@
</div>
<div class="circle-tile-content lightblue">
<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 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>
@ -67,11 +67,10 @@
</div>
<div class="circle-tile-content lightblue">
<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="h6" id="b-nextdiffc">{if $GLOBAL.nethashrate > 0}Change in {$NETWORK.BlocksUntilDiffChange} Blocks{else}No Estimates{/if}</p>
<p class="h5" id="b-nextdiff">{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 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>

View File

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

View File

@ -37,10 +37,10 @@
</div>
<div class="circle-tile-content lightblue">
<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 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>
@ -67,11 +67,10 @@
</div>
<div class="circle-tile-content lightblue">
<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="h6" id="b-nextdiffc">{if $GLOBAL.nethashrate > 0}Change in {$NETWORK.BlocksUntilDiffChange} Blocks{else}No Estimates{/if}</p>
<p class="h5" id="b-nextdiff">{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</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>