I've now got all shares submitted by my node in a nice fast DB.
They are reported for the node on the main page, and per miner on the miner dashboard page, below is a shot from the miner dashboard. I'm going to do the same for blocks next...
nice! care to share or collaborate on my front end? would love to be able to display more stats persisted over restarts etc.
I'm happy to share everything I'm doing....
This code is not optimized and is likely still buggy, the nice thing is it only affects the front end, so bugs will not hamper mining in any way. Any contributions or suggestions are appreciated.
At some point I may clean everything up and post to GitHub, but that is a ways off....
This was written for a LAMP stack, should work on other platforms, but untested....
You will also need to move your p2pool "front end" and logfile to a directory accessible by your web server and where php can run.
The included CRUD class is here: http://www.phpro.org/classes/PDO-CRUD.html
MySQL DB Table:
--
-- Table structure for table `found_shares`
--
CREATE TABLE IF NOT EXISTS `found_shares` (
`id` int(11) NOT NULL,
`address` varchar(34) NOT NULL,
`share` varchar(15) NOT NULL,
`time` datetime NOT NULL,
`doa` tinyint(1) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Indexes for table `found_shares`
--
ALTER TABLE `found_shares`
ADD PRIMARY KEY (`id`);
--
-- AUTO_INCREMENT for table `found_shares`
--
ALTER TABLE `found_shares`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
Cron job that populates the DB, set to run every minute:
// ******************************************** //
// P2Pool to MySQL
// File: cron.php
// Author: Ian T. (bitcointalk: windpath)
// Web: http://www.CoinCadence.com
// Sample: http://mining.CoinCadence.com
// ******************************************** //
// Error reporting (should be commented out when live)
//ini_set('display_startup_errors',1);
//ini_set('display_errors',1);
//error_reporting(-1);
// ******************************************** //
// Set below variables
// ******************************************** //
// MySQL Database
$THE_HOST = "DB_HOST";
$THE_USER = "DB_USER";
$THE_PWD = "DB_PWD";
$THE_DB = "DB_DB";
// Path to P2Pool log
// Must be readable and writable by PHP
// Custom P2Pool log location can be set when starting P2Pool. Example:
// --logfile /path/to/log/p2pool
// !! --> Make sure it is not publicly readable <-- !!
$log_path = '/path/to/log/p2pool';
// ******************************************** //
// Edit past here at your own risk...
// ******************************************** //
// Pattern to match
$share_pattern = '/GOT\ SHARE/';
// ******************************************** //
// set up crud DB class
// ******************************************** //
include 'crud.php';
$crud = new crud();
$setDsn = "mysql:dbname=".$THE_DB.";host=".$THE_HOST;
$crud->dsn = $setDsn;
$crud->username = $THE_USER;
$crud->password = $THE_PWD;
// ******************************************** //
// Function Calls
// ******************************************** //
getShares($share_pattern, $log_path);
maintainFile($log_path);
// ******************************************** //
// Functions
// ******************************************** //
function maintainFile($log_path)
{
if (filesize($log_path) > 25000000) // 25MB
{
$log_backup = $log_path.time().".bak";
rename ($log_path, $log_backup);
}
return;
}
function getShares($share_pattern, $log_path)
{
$values = array();
$result = preg_grep($share_pattern, file($log_path));
if ($result != NULL)
{
$rawShares = array_reverse($result);
$shareCount = count($rawShares);
$x = $shareCount;
foreach($rawShares as $share)
{
if ($x > 0)
{
$pieces = explode(" ", $share);
$shareDate = $pieces[0]." ".$pieces[1];
$shareMiner = $pieces[4];
$shareShare = $pieces[5];
if (isset($pieces[10])) { $shareDoa = 1; } else { $shareDoa = 0; }
if(testShare($shareShare, $shareDate) == false)
{
$values[] = array('address'=>$shareMiner, 'share'=>$shareShare, 'time'=>$shareDate, 'doa'=>$shareDoa);
}
$x--;
}
}
insertShares($values);
}
}
function insertShares($values)
{
if(!empty($values))
{
global $crud;
$crud->dbInsert('found_shares', $values);
}
}
function testShare($shareShare, $shareDate)
{
global $crud;
$sql = "SELECT * FROM `found_shares` WHERE `share` = '".$shareShare."' AND `time` = '".$shareDate."'";
$records = $crud->rawSelect($sql);
$shares = $records->fetchAll(PDO::FETCH_ASSOC);
if(empty($shares)) { return false; } else { return true; }
}
?>
Front end:
This still needs a lot of work, presentation needs to be removed from logic...
Display Shares, this file is "included" in the front end and dumps out a formatted HTML table for now:
// ******************************************** //
// P2Pool to MySQL
// File: shares.php Web Share Explorer
// Author: Ian T. (bitcointalk: windpath)
// Web: http://www.CoinCadence.com
// Sample: http://mining.CoinCadence.com
// ******************************************** //
// Error reporting (should be commented out when live)
//ini_set('display_startup_errors',1);
//ini_set('display_errors',1);
//error_reporting(-1);
// ******************************************** //
// Set below variables
// ******************************************** //
// MySQL Database
$THE_HOST = "DB_HOST";
$THE_USER = "DB_USER";
$THE_PWD = "DB_PWD";
$THE_DB = "DB_DB";
// ******************************************** //
// Edit past here at your own risk...
// ******************************************** //
// ******************************************** //
// set up crud DB class
// ******************************************** //
include 'crud.php';
$crud = new crud();
$setDsn = "mysql:dbname=".$THE_DB.";host=".$THE_HOST;
$crud->dsn = $setDsn;
$crud->username = $THE_USER;
$crud->password = $THE_PWD;
$records = $crud->rawSelect('SELECT SQL_CALC_FOUND_ROWS * FROM found_shares ORDER BY time DESC LIMIT 20');
$rows = $records->fetchAll(PDO::FETCH_ASSOC);
$count = $crud->rawSelect("SELECT FOUND_ROWS()");
$totalRows = $count->fetch(PDO::FETCH_ASSOC);
echo "1 - ".count($rows)." of ".$totalRows['FOUND_ROWS()']." Shares";
echo '';
'; Age Bitcoin Address Share Status
foreach($rows as $row)
{
$time = strtotime($row['time']);
$timeSince = humanTiming($time);
$shareMiner = $row['address'].' .$row['address'].'" TARGET="_NEW">(view)';
$shareShare = $row['share'];
if($row['doa'] == 0) { $shareStatus = 'accepted'; } else { $shareStatus = 'DOA'; }
echo ""; $timeSince ago $shareMiner $shareShare $shareStatus
}
echo '
function humanTiming ($time)
{
$time = time() - $time; // to get the time since that moment
$tokens = array (
31536000 => 'year',
2592000 => 'month',
604800 => 'week',
86400 => 'day',
3600 => 'hour',
60 => 'minute',
1 => 'second'
);
foreach ($tokens as $unit => $text) {
if ($time < $unit) continue;
$numberOfUnits = floor($time / $unit);
return $numberOfUnits.' '.$text.(($numberOfUnits>1)?'s':'');
}
}
?>
So that's where I'm at, more to come....