Merge pull request #161 from TheSerapher/issue-70

Issue 70
This commit is contained in:
Sebastian Grewe 2013-06-10 10:03:09 -07:00
commit 27176d2e8a
8 changed files with 169 additions and 12 deletions

105
cronjobs/pps_payout.php Executable file
View File

@ -0,0 +1,105 @@
#!/usr/bin/php
<?php
/*
Copyright:: 2013, Sebastian Grewe
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Include all settings and classes
require_once('shared.inc.php');
// Fetch all transactions since our last block
if ( $bitcoin->can_connect() === true ){
$dDifficulty = $bitcoin->getdifficulty();
} else {
verbose("Aborted: " . $bitcoin->can_connect() . "\n");
exit(1);
}
// Value per share calculation
$pps_value = number_format(round(50 / (pow(2,32) * $dDifficulty) * pow(2, $config['difficulty']), 12) ,12);
// Find our last share accounted and last inserted share for PPS calculations
$iPreviousShareId = $setting->getValue('pps_last_share_id');
$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);
verbose("ID\tUsername\tInvalid\tValid\t\tPPS Value\t\tPayout\t\tDonation\tFee\t\tStatus\n");
foreach ($aAccountShares as $aData) {
// Take our valid shares and multiply by per share value
$aData['payout'] = number_format(round($aData['valid'] * $pps_value, 8), 8);
// Defaults
$aData['fee' ] = 0;
$aData['donation'] = 0;
// Calculate block fees
if ($config['fees'] > 0)
$aData['fee'] = number_format(round($config['fees'] / 100 * $aData['payout'], 8), 8);
// Calculate donation amount
$aData['donation'] = number_format(round($user->getDonatePercent($user->getUserId($aData['username'])) / 100 * ( $aData['payout'] - $aData['fee']), 8), 8);
verbose($aData['id'] . "\t" .
$aData['username'] . "\t" .
$aData['invalid'] . "\t" .
$aData['valid'] . "\t*\t" .
$pps_value . "\t=\t" .
$aData['payout'] . "\t" .
$aData['donation'] . "\t" .
$aData['fee'] . "\t");
$strStatus = "OK";
// Add new credit transaction
if (!$transaction->addTransaction($aData['id'], $aData['payout'], 'Credit_PPS'))
$strStatus = "Transaction Failed";
// Add new fee debit for this block
if ($aData['fee'] > 0 && $config['fees'] > 0)
if (!$transaction->addTransaction($aData['id'], $aData['fee'], 'Fee_PPS'))
$strStatus = "Fee Failed";
// Add new donation debit
if ($aData['donation'] > 0)
if (!$transaction->addTransaction($aData['id'], $aData['donation'], 'Donation_PPS'))
$strStatus = "Donation Failed";
verbose($strStatus . "\n");
}
// Store our last inserted ID for the next run
$setting->setValue('pps_last_share_id', $iLastShareId);
verbose("\n\n------------------------------------------------------------------------------------\n\n");
// Fetch all unaccounted blocks
$aAllBlocks = $block->getAllUnaccounted('ASC');
if (empty($aAllBlocks)) {
verbose("No new unaccounted blocks found\n");
}
// Go through blocks and archive/delete shares that have been accounted for
foreach ($aAllBlocks as $iIndex => $aBlock) {
$dummy = $iIndex - 1;
if ($config['archive_shares'] && $aBlock['share_id'] < $iLastShareId) {
$share->moveArchive($aBlock['share_id'], $aBlock['id'], @$aAllBlocks[$dummy]['share_id']);
}
if ($aBlock['share_id'] < $iLastShareId && !$share->deleteAccountedShares($aBlock['share_id'], @$aAllBlocks[$dummy]['share_id'])) {
verbose("\nERROR : Failed to delete accounted shares from " . $aBlock['share_id'] . " to " . @$aAllBlocks[$dummy]['share_id'] . ", aborting!\n");
exit(1);
}
}
?>

View File

@ -44,6 +44,21 @@ class Share {
return $this->table;
}
/**
* Get last inserted Share ID from Database
* Used for PPS calculations without moving to archive
**/
public function getLastInsertedShareId() {
$stmt = $this->mysqli->prepare("
SELECT MAX(id) AS id FROM $this->table
");
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_object()->id;
// Catchall
$this->setErrorMessage('Failed to fetch last inserted share ID');
return false;
}
/**
* Get all valid shares for this round
* @param previous_upstream int Previous found share accepted by upstream to limit results

View File

@ -131,8 +131,10 @@ class Transaction {
SELECT sum(t.amount) AS credit
FROM $this->table AS t
LEFT JOIN " . $this->block->getTableName() . " AS b ON t.block_id = b.id
WHERE t.type IN ('Credit','Bonus')
AND b.confirmations >= " . $this->config['confirmations'] . "
WHERE (
( t.type IN ('Credit','Bonus') AND b.confirmations >= ? ) OR
( t.type = 'Credit_PPS' )
)
) AS t1,
(
SELECT sum(t.amount) AS debit
@ -143,10 +145,12 @@ class Transaction {
SELECT sum(t.amount) AS other
FROM " . $this->table . " AS t
LEFT JOIN " . $this->block->getTableName() . " AS b ON t.block_id = b.id
WHERE t.type IN ('Donation','Fee')
AND b.confirmations >= " . $this->config['confirmations'] . "
WHERE (
( t.type IN ('Donation','Fee') AND b.confirmations >= ? ) OR
t.type IN ('Donation_PPS','Fee_PPS')
)
) AS t3");
if ($this->checkStmt($stmt) && $stmt->execute() && $stmt->bind_result($dBalance) && $stmt->fetch())
if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $this->config['confirmations'], $this->config['confirmations']) && $stmt->execute() && $stmt->bind_result($dBalance) && $stmt->fetch())
return $dBalance;
// Catchall
$this->setErrorMessage('Unable to find locked credits for all users');
@ -168,8 +172,11 @@ class Transaction {
SELECT sum(t.amount) AS credit
FROM $this->table AS t
LEFT JOIN " . $this->block->getTableName() . " AS b ON t.block_id = b.id
WHERE t.type IN ('Credit','Bonus')
AND b.confirmations >= ?
WHERE
(
( t.type IN ('Credit','Bonus') AND b.confirmations >= ? ) OR
( t.type = 'Credit_PPS' )
)
AND t.account_id = ?
) AS t1,
(
@ -182,8 +189,11 @@ class Transaction {
SELECT sum(t.amount) AS other
FROM $this->table AS t
LEFT JOIN " . $this->block->getTableName() . " AS b ON t.block_id = b.id
WHERE t.type IN ('Donation','Fee')
AND b.confirmations >= ?
WHERE
(
( t.type IN ('Donation','Fee') AND b.confirmations >= ? ) OR
( t.type IN ('Donation_PPS', 'Fee_PPS') )
)
AND t.account_id = ?
) AS t3
");

View File

@ -35,6 +35,7 @@ $config = array(
'email' => 'test@example.com', // Mail address used for notifications
),
'block_bonus' => 0,
'payout_system' => 'pps', // Set your payout here so template changes are activated
'archive_shares' => true, // Store accounted shares in archive table?
'blockexplorer' => 'http://explorer.litecoin.net/search?q=', // URL for block searches, prefixed to each block number
'chaininfo' => 'http://allchains.info', // Link to Allchains for Difficulty information

View File

@ -12,12 +12,18 @@ $aRoundShares = $statistics->getRoundShares();
$iCurrentActiveWorkers = $worker->getCountAllActiveWorkers();
$iCurrentPoolHashrate = $statistics->getCurrentHashrate();
$iCurrentPoolShareRate = $statistics->getCurrentShareRate();
if ($bitcoin->can_connect() === true){
$dDifficulty = $bitcoin->query('getdifficulty');
} else {
$dDifficulty = 1;
}
$aGlobal = array(
'slogan' => $config['website']['slogan'],
'websitename' => $config['website']['name'],
'hashrate' => $iCurrentPoolHashrate,
'sharerate' => $iCurrentPoolShareRate,
'ppsvalue' => number_format(round(50 / (pow(2,32) * $dDifficulty) * pow(2, $config['difficulty']), 12) ,12),
'workers' => $iCurrentActiveWorkers,
'roundshares' => $aRoundShares,
'fees' => $config['fees'],
@ -27,6 +33,7 @@ $aGlobal = array(
'blockexplorer' => $config['blockexplorer'],
'chaininfo' => $config['chaininfo'],
'config' => array(
'payout_system' => $config['payout_system'],
'ap_threshold' => array(
'min' => $config['ap_threshold']['min'],
'max' => $config['ap_threshold']['max']

View File

@ -19,6 +19,9 @@
(($TRANSACTIONS[transaction].type == 'Credit' or $TRANSACTIONS[transaction].type == 'Bonus')and $TRANSACTIONS[transaction].confirmations >= $GLOBAL.confirmations)
or ($TRANSACTIONS[transaction].type == 'Donation' and $TRANSACTIONS[transaction].confirmations >= $GLOBAL.confirmations)
or ($TRANSACTIONS[transaction].type == 'Fee' and $TRANSACTIONS[transaction].confirmations >= $GLOBAL.confirmations)
or $TRANSACTIONS[transaction].type == 'Credit_PPS'
or $TRANSACTIONS[transaction].type == 'Fee_PPS'
or $TRANSACTIONS[transaction].type == 'Donation_PPS'
or $TRANSACTIONS[transaction].type == 'Debit_AP'
or $TRANSACTIONS[transaction].type == 'Debit_MP'
)}
@ -28,7 +31,7 @@
<td>{$TRANSACTIONS[transaction].type}</td>
<td>{$TRANSACTIONS[transaction].coin_address}</td>
<td>{if $TRANSACTIONS[transaction].height == 0}n/a{else}{$TRANSACTIONS[transaction].height}{/if}</td>
<td><font color="{if $TRANSACTIONS[transaction].type == 'Credit' or $TRANSACTIONS[transaction].type == 'Bonus'}green{else}red{/if}">{$TRANSACTIONS[transaction].amount}</td>
<td><font color="{if $TRANSACTIONS[transaction].type == 'Credit' or $TRANSACTIONS[transaction].type == 'Credit_PPS' or $TRANSACTIONS[transaction].type == 'Bonus'}green{else}red{/if}">{$TRANSACTIONS[transaction].amount}</td>
</tr>
{/if}
{/section}

View File

@ -6,8 +6,20 @@
</div>
<div class="block_content" style="padding-top:10px;">
<table class="sidebar" style="width: 196px">
<tr><td colspan="2"><b>Your Hashrate</b></td></tr>
<tr><td colspan="2" class="right">{$GLOBAL.userdata.hashrate|number_format} KH/s</td></tr>
<tr>
<td colspan="2"><b><u>Your Stats</u></b></td>
</tr>
<tr>
<td><b>Hashrate</b></td>
<td class="right">{$GLOBAL.userdata.hashrate|number_format} KH/s</td>
</tr>
{if $GLOBAL.config.payout_system == 'pps'}
<tr>
<td><b>PPS Value</b></td>
<td>{$GLOBAL.ppsvalue}</td>
</tr>
{/if}
{if $GLOBAL.config.payout_system != 'pps'}
<tr>
<td colspan="2"><b><u>Unpaid Shares</u></b> <span id='tt'><img src='{$PATH}/images/questionmark.png' height='15px' width='15px' title='Submitted shares between the last 120 confirms block until now.'></span></td>
</tr>
@ -19,6 +31,7 @@
<td><b>Pool Valid</td>
<td class="right"><i>{$GLOBAL.roundshares.valid|number_format}</i> <font size='1px'></font></b></td>
</tr>
{/if}
<tr>
<td colspan="2"><b><u>Round Shares</u></b> <span id='tt'><img src='{$PATH}/images/questionmark.png' height='15px' width='15px' title='Submitted shares since last found block (ie. round shares)'></span></td>
</tr>
@ -34,6 +47,7 @@
<td><b>Your Invalid</b></td>
<td class="right"><i>{$GLOBAL.userdata.shares.invalid|number_format}</i><font size='1px'></font></td>
</tr>
{if $GLOBAL.config.payout_system != 'pps'}
<tr>
<td colspan="2"><b><u>LTC Round Estimate</u></b></td>
</tr>
@ -53,6 +67,7 @@
<td><b>Payout</b></td>
<td class="right">{$GLOBAL.userdata.est_payout|number_format:"3"}</td>
</tr>
{/if}
<tr><td colspan="2">&nbsp;</td></tr>
<tr><td colspan="2"><b><u>Account Balance</u></b></td></tr>
<tr><td colspan="2" class="right"><b>{$GLOBAL.userdata.balance|default:"0"} LTC</td></tr>

View File

@ -0,0 +1 @@
ALTER TABLE `transactions` CHANGE `type` `type` ENUM( 'Credit', 'Debit_MP', 'Debit_AP', 'Donation', 'Fee', 'Orphan_Credit', 'Orphan_Fee', 'Orphan_Donation', 'Bonus', 'Orphan_Bonus', 'Credit_PPS', 'Debit_PPS', 'Donation_PPS' ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL;