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; 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 * Get all valid shares for this round
* @param previous_upstream int Previous found share accepted by upstream to limit results * @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 SELECT sum(t.amount) AS credit
FROM $this->table AS t FROM $this->table AS t
LEFT JOIN " . $this->block->getTableName() . " AS b ON t.block_id = b.id LEFT JOIN " . $this->block->getTableName() . " AS b ON t.block_id = b.id
WHERE t.type IN ('Credit','Bonus') WHERE (
AND b.confirmations >= " . $this->config['confirmations'] . " ( t.type IN ('Credit','Bonus') AND b.confirmations >= ? ) OR
( t.type = 'Credit_PPS' )
)
) AS t1, ) AS t1,
( (
SELECT sum(t.amount) AS debit SELECT sum(t.amount) AS debit
@ -143,10 +145,12 @@ class Transaction {
SELECT sum(t.amount) AS other SELECT sum(t.amount) AS other
FROM " . $this->table . " AS t FROM " . $this->table . " AS t
LEFT JOIN " . $this->block->getTableName() . " AS b ON t.block_id = b.id LEFT JOIN " . $this->block->getTableName() . " AS b ON t.block_id = b.id
WHERE t.type IN ('Donation','Fee') WHERE (
AND b.confirmations >= " . $this->config['confirmations'] . " ( t.type IN ('Donation','Fee') AND b.confirmations >= ? ) OR
t.type IN ('Donation_PPS','Fee_PPS')
)
) AS t3"); ) 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; return $dBalance;
// Catchall // Catchall
$this->setErrorMessage('Unable to find locked credits for all users'); $this->setErrorMessage('Unable to find locked credits for all users');
@ -168,8 +172,11 @@ class Transaction {
SELECT sum(t.amount) AS credit SELECT sum(t.amount) AS credit
FROM $this->table AS t FROM $this->table AS t
LEFT JOIN " . $this->block->getTableName() . " AS b ON t.block_id = b.id LEFT JOIN " . $this->block->getTableName() . " AS b ON t.block_id = b.id
WHERE t.type IN ('Credit','Bonus') WHERE
AND b.confirmations >= ? (
( t.type IN ('Credit','Bonus') AND b.confirmations >= ? ) OR
( t.type = 'Credit_PPS' )
)
AND t.account_id = ? AND t.account_id = ?
) AS t1, ) AS t1,
( (
@ -182,8 +189,11 @@ class Transaction {
SELECT sum(t.amount) AS other SELECT sum(t.amount) AS other
FROM $this->table AS t FROM $this->table AS t
LEFT JOIN " . $this->block->getTableName() . " AS b ON t.block_id = b.id LEFT JOIN " . $this->block->getTableName() . " AS b ON t.block_id = b.id
WHERE t.type IN ('Donation','Fee') WHERE
AND b.confirmations >= ? (
( t.type IN ('Donation','Fee') AND b.confirmations >= ? ) OR
( t.type IN ('Donation_PPS', 'Fee_PPS') )
)
AND t.account_id = ? AND t.account_id = ?
) AS t3 ) AS t3
"); ");

View File

@ -35,6 +35,7 @@ $config = array(
'email' => 'test@example.com', // Mail address used for notifications 'email' => 'test@example.com', // Mail address used for notifications
), ),
'block_bonus' => 0, 'block_bonus' => 0,
'payout_system' => 'pps', // Set your payout here so template changes are activated
'archive_shares' => true, // Store accounted shares in archive table? '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 '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 'chaininfo' => 'http://allchains.info', // Link to Allchains for Difficulty information

View File

@ -12,12 +12,18 @@ $aRoundShares = $statistics->getRoundShares();
$iCurrentActiveWorkers = $worker->getCountAllActiveWorkers(); $iCurrentActiveWorkers = $worker->getCountAllActiveWorkers();
$iCurrentPoolHashrate = $statistics->getCurrentHashrate(); $iCurrentPoolHashrate = $statistics->getCurrentHashrate();
$iCurrentPoolShareRate = $statistics->getCurrentShareRate(); $iCurrentPoolShareRate = $statistics->getCurrentShareRate();
if ($bitcoin->can_connect() === true){
$dDifficulty = $bitcoin->query('getdifficulty');
} else {
$dDifficulty = 1;
}
$aGlobal = array( $aGlobal = array(
'slogan' => $config['website']['slogan'], 'slogan' => $config['website']['slogan'],
'websitename' => $config['website']['name'], 'websitename' => $config['website']['name'],
'hashrate' => $iCurrentPoolHashrate, 'hashrate' => $iCurrentPoolHashrate,
'sharerate' => $iCurrentPoolShareRate, 'sharerate' => $iCurrentPoolShareRate,
'ppsvalue' => number_format(round(50 / (pow(2,32) * $dDifficulty) * pow(2, $config['difficulty']), 12) ,12),
'workers' => $iCurrentActiveWorkers, 'workers' => $iCurrentActiveWorkers,
'roundshares' => $aRoundShares, 'roundshares' => $aRoundShares,
'fees' => $config['fees'], 'fees' => $config['fees'],
@ -27,6 +33,7 @@ $aGlobal = array(
'blockexplorer' => $config['blockexplorer'], 'blockexplorer' => $config['blockexplorer'],
'chaininfo' => $config['chaininfo'], 'chaininfo' => $config['chaininfo'],
'config' => array( 'config' => array(
'payout_system' => $config['payout_system'],
'ap_threshold' => array( 'ap_threshold' => array(
'min' => $config['ap_threshold']['min'], 'min' => $config['ap_threshold']['min'],
'max' => $config['ap_threshold']['max'] '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) (($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 == 'Donation' and $TRANSACTIONS[transaction].confirmations >= $GLOBAL.confirmations)
or ($TRANSACTIONS[transaction].type == 'Fee' 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_AP'
or $TRANSACTIONS[transaction].type == 'Debit_MP' or $TRANSACTIONS[transaction].type == 'Debit_MP'
)} )}
@ -28,7 +31,7 @@
<td>{$TRANSACTIONS[transaction].type}</td> <td>{$TRANSACTIONS[transaction].type}</td>
<td>{$TRANSACTIONS[transaction].coin_address}</td> <td>{$TRANSACTIONS[transaction].coin_address}</td>
<td>{if $TRANSACTIONS[transaction].height == 0}n/a{else}{$TRANSACTIONS[transaction].height}{/if}</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> </tr>
{/if} {/if}
{/section} {/section}

View File

@ -6,8 +6,20 @@
</div> </div>
<div class="block_content" style="padding-top:10px;"> <div class="block_content" style="padding-top:10px;">
<table class="sidebar" style="width: 196px"> <table class="sidebar" style="width: 196px">
<tr><td colspan="2"><b>Your Hashrate</b></td></tr> <tr>
<tr><td colspan="2" class="right">{$GLOBAL.userdata.hashrate|number_format} KH/s</td></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> <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> <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> </tr>
@ -19,6 +31,7 @@
<td><b>Pool Valid</td> <td><b>Pool Valid</td>
<td class="right"><i>{$GLOBAL.roundshares.valid|number_format}</i> <font size='1px'></font></b></td> <td class="right"><i>{$GLOBAL.roundshares.valid|number_format}</i> <font size='1px'></font></b></td>
</tr> </tr>
{/if}
<tr> <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> <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> </tr>
@ -34,6 +47,7 @@
<td><b>Your Invalid</b></td> <td><b>Your Invalid</b></td>
<td class="right"><i>{$GLOBAL.userdata.shares.invalid|number_format}</i><font size='1px'></font></td> <td class="right"><i>{$GLOBAL.userdata.shares.invalid|number_format}</i><font size='1px'></font></td>
</tr> </tr>
{if $GLOBAL.config.payout_system != 'pps'}
<tr> <tr>
<td colspan="2"><b><u>LTC Round Estimate</u></b></td> <td colspan="2"><b><u>LTC Round Estimate</u></b></td>
</tr> </tr>
@ -53,6 +67,7 @@
<td><b>Payout</b></td> <td><b>Payout</b></td>
<td class="right">{$GLOBAL.userdata.est_payout|number_format:"3"}</td> <td class="right">{$GLOBAL.userdata.est_payout|number_format:"3"}</td>
</tr> </tr>
{/if}
<tr><td colspan="2">&nbsp;</td></tr> <tr><td colspan="2">&nbsp;</td></tr>
<tr><td colspan="2"><b><u>Account Balance</u></b></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> <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;