Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 36 additions & 34 deletions cronjobs/notifications.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,47 +29,49 @@
$monitoring->endCronjob($cron_name, 'E0009', 0, true, false);
}

$log->logDebug(" IDLE Worker Notifications ...");
// Find all IDLE workers
$aWorkers = $worker->getAllIdleWorkers();
if (empty($aWorkers)) {
$log->logDebug(" no idle workers found");
} else {
$log->logInfo(" found " . count($aWorkers) . " IDLE workers");
foreach ($aWorkers as $aWorker) {
$aData = $aWorker;
$aData['username'] = $user->getUserName($aWorker['account_id']);
$aData['subject'] = 'IDLE Worker : ' . $aWorker['username'];
$aData['worker'] = $aWorker['username'];
$aData['email'] = $user->getUserEmail($aData['username']);
$log->logDebug(" " . $aWorker['username'] . "...");
if (!$notification->sendNotification($aWorker['account_id'], 'idle_worker', $aData))
$log->logDebug(" Failed sending notifications: " . $notification->getCronError());
if ($setting->getValue('notifications_disable_idle_worker') != 1) {
$log->logDebug(" IDLE Worker Notifications ...");
// Find all IDLE workers
$aWorkers = $worker->getAllIdleWorkers();
if (empty($aWorkers)) {
$log->logDebug(" no idle workers found");
} else {
$log->logInfo(" found " . count($aWorkers) . " IDLE workers");
foreach ($aWorkers as $aWorker) {
$aData = $aWorker;
$aData['username'] = $user->getUserName($aWorker['account_id']);
$aData['subject'] = 'IDLE Worker : ' . $aWorker['username'];
$aData['worker'] = $aWorker['username'];
$aData['email'] = $user->getUserEmail($aData['username']);
$log->logDebug(" " . $aWorker['username'] . "...");
if (!$notification->sendNotification($aWorker['account_id'], 'idle_worker', $aData))
$log->logDebug(" Failed sending notifications: " . $notification->getCronError());
}
}
}


$log->logDebug(" Reset IDLE Worker Notifications ...");
// We notified, lets check which recovered
$aNotifications = $notification->getAllActive('idle_worker');
if (!empty($aNotifications)) {
$log->logInfo(" found " . count($aNotifications) . " active notification(s)");
foreach ($aNotifications as $aNotification) {
$aData = json_decode($aNotification['data'], true);
$aWorker = $worker->getWorker($aData['id']);
$log->logDebug(" " . $aWorker['username'] . " ...");
if ($aWorker['hashrate'] > 0) {
if ($notification->setInactive($aNotification['id'])) {
$log->logDebug(" updated #" . $aNotification['id'] . " for " . $aWorker['username'] . " as inactive");
$log->logDebug(" Reset IDLE Worker Notifications ...");
// We notified, lets check which recovered
$aNotifications = $notification->getAllActive('idle_worker');
if (!empty($aNotifications)) {
$log->logInfo(" found " . count($aNotifications) . " active notification(s)");
foreach ($aNotifications as $aNotification) {
$aData = json_decode($aNotification['data'], true);
$aWorker = $worker->getWorker($aData['id']);
$log->logDebug(" " . $aWorker['username'] . " ...");
if ($aWorker['hashrate'] > 0) {
if ($notification->setInactive($aNotification['id'])) {
$log->logDebug(" updated #" . $aNotification['id'] . " for " . $aWorker['username'] . " as inactive");
} else {
$log->logError(" failed to update #" . $aNotification['id'] . " for " . $aWorker['username']);
}
} else {
$log->logError(" failed to update #" . $aNotification['id'] . " for " . $aWorker['username']);
$log->logDebug(" still inactive");
}
} else {
$log->logDebug(" still inactive");
}
} else {
$log->logDebug(" no active IDLE worker notifications");
}
} else {
$log->logDebug(" no active IDLE worker notifications");
}

require_once('cron_end.inc.php');
Expand Down
22 changes: 19 additions & 3 deletions cronjobs/pplns_payout.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,8 @@
}

// Table header for account shares
$strLogMask = "| %5.5s | %-15.15s | %15.15s | %15.15s | %12.12s | %20.20s | %20.20s | %20.20s |";
$log->logInfo(sprintf($strLogMask, 'ID', 'Username', 'Valid', 'Invalid', 'Percentage', 'Payout', 'Donation', 'Fee'));
$strLogMask = "| %5.5s | %-15.15s | %15.15s | %15.15s | %12.12s | %15.15s | %15.15s | %15.15s | %15.15s |";
$log->logInfo(sprintf($strLogMask, 'ID', 'Username', 'Valid', 'Invalid', 'Percentage', 'Payout', 'Donation', 'Fee', 'Bonus'));

// Loop through all accounts that have found shares for this round
foreach ($aTotalAccountShares as $key => $aData) {
Expand All @@ -201,16 +201,28 @@
// Defaults
$aData['fee' ] = 0;
$aData['donation'] = 0;
$aData['pool_bonus'] = 0;

// Calculate pool fees
if ($config['fees'] > 0 && $aData['no_fees'] == 0)
$aData['fee'] = round($config['fees'] / 100 * $aData['payout'], 8);

// 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);
} else {
$aData['pool_bonus'] = round(( $config['pool_bonus'] / 100 ) * $aData['payout'], 8);
}
}

// Calculate donation amount, fees not included
$aData['donation'] = round($user->getDonatePercent($user->getUserId($aData['username'])) / 100 * ( $aData['payout'] - $aData['fee']), 8);

// Verbose output of this users calculations
$log->logInfo(
sprintf($strLogMask, $aData['id'], $aData['username'], $aData['pplns_valid'], $aData['pplns_invalid'],
number_format($aData['percentage'], 8), number_format($aData['payout'], 8), number_format($aData['donation'], 8), number_format($aData['fee'], 8)
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)
)
);

Expand All @@ -225,6 +237,10 @@
if ($aData['donation'] > 0)
if (!$transaction->addTransaction($aData['id'], $aData['donation'], 'Donation', $aBlock['id']))
$log->logFatal('Failed to insert new Donation transaction to database for ' . $aData['username'] . ': ' . $transaction->getCronError() . 'on block ' . $aBlock['id']);
// Add new bonus credit
if ($aData['pool_bonus'] > 0)
if (!$transaction->addTransaction($aData['id'], $aData['pool_bonus'], 'Bonus', $aBlock['id']))
$log->logFatal('Failed to insert new Bonus transaction to database for ' . $aData['username'] . ': ' . $transaction->getCronError());
}

// Add full round share statistics
Expand Down
22 changes: 19 additions & 3 deletions cronjobs/proportional_payout.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@

$count = 0;
// Table header for account shares
$strLogMask = "| %10.10s | %-5.5s | %15.15s | %15.15s | %12.12s | %20.20s | %20.20s | %20.20s |";
$log->logInfo(sprintf($strLogMask, 'Block', 'ID', 'Username', 'Valid', 'Invalid', 'Percentage', 'Payout', 'Donation', 'Fee'));
$strLogMask = "| %10.10s | %-5.5s | %15.15s | %15.15s | %12.12s | %12.12s | %15.15s | %15.15s | %15.15s | %15.15s |";
$log->logInfo(sprintf($strLogMask, 'Block', 'ID', 'Username', 'Valid', 'Invalid', 'Percentage', 'Payout', 'Donation', 'Fee', 'Bonus'));
foreach ($aAllBlocks as $iIndex => $aBlock) {
// If we have unaccounted blocks without share_ids, they might not have been inserted yet
if (!$aBlock['share_id']) {
Expand Down Expand Up @@ -86,18 +86,30 @@
// Defaults
$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);

// Calculate pool fees if they apply
if ($config['fees'] > 0 && $aData['no_fees'] == 0)
$aData['fee'] = round($config['fees'] / 100 * $aData['payout'], 8);

// 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);
} else {
$aData['pool_bonus'] = round(( $config['pool_bonus'] / 100 ) * $aData['payout'], 8);
}
}

// Calculate donation amount, fees not included
$aData['donation'] = round($user->getDonatePercent($user->getUserId($aData['username'])) / 100 * ( $aData['payout'] - $aData['fee']), 8);

// 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['percentage'], 8), number_format($aData['payout'], 8), number_format($aData['donation'], 8), number_format($aData['fee'], 8), number_format($aData['pool_bonus'], 8))
);

// Update user share statistics
Expand All @@ -114,6 +126,10 @@
if ($aData['donation'] > 0)
if (!$transaction->addTransaction($aData['id'], $aData['donation'], 'Donation', $aBlock['id']))
$log->logFatal('Failed to insert new Donation transaction to database for ' . $aData['username'] . ': ' . $transaction->getCronError());
// Add new bonus credit
if ($aData['pool_bonus'] > 0)
if (!$transaction->addTransaction($aData['id'], $aData['pool_bonus'], 'Bonus', $aBlock['id']))
$log->logFatal('Failed to insert new Bonus transaction to database for ' . $aData['username'] . ': ' . $transaction->getCronError());
}

// Add block as accounted for into settings table
Expand Down
44 changes: 23 additions & 21 deletions public/include/admin_checks.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,27 @@
$notice = array();
$enotice = array();
$error = array();

// setup some basic stuff for checking - getuid/getpwuid not available on mac/windows
$apache_user = 'unknown';
if (substr_count(strtolower(PHP_OS), 'nix') > 0 || substr_count(strtolower(PHP_OS), 'linux') > 0) {
$apache_user = (function_exists('posix_getuid')) ? posix_getuid() : 'unknown';
$apache_user = (function_exists('posix_getpwuid')) ? posix_getpwuid($apache_user) : $apache_user;
}

// setup checks
// logging
if ($config['logging']['enabled']) {
if (!is_writable($config['logging']['path'])) {
$error[] = "Logging is enabled but we can't write in the logging path";
$error[] = "Logging is enabled but we can't write in the logfile path";
}
}

// check if memcache isn't available but enabled in config -> error
if (!class_exists('Memcached') && $config['memcache']['enabled']) {
$error[] = "You have memcache enabled in your config and it's not available. Install the package on your system.";
$error[] = "You have memcached enabled in your config and it's not available as a PHP module. Install the package on your system.";
}

// if it's not enabled, test it if it exists, if it works -> error tell them to enable, -> otherwise notice it's disabled
if (!$config['memcache']['enabled']) {
if (PHP_OS == 'WINNT') {
Expand All @@ -38,28 +40,32 @@
$memcache_test_get = @$memcache_test->get('test_mpos_setval');
}
if (class_exists('Memcached') && $memcache_test_get == $randmctv) {
$error[] = "You have memcache disabled in the config and it's available & works! Enable it.";
$error[] = "You have memcache disabled in the config but it's available and works! Enable it for best performance.";
} else {
$notice[] = "Memcache is disabled; Almost every linux distro has packages for it, you should be using it if you can.";
}
}

// check if htaccess exists
if (!file_exists(BASEPATH.".htaccess")) {
$htaccess_link = "<a href='https://github.com/MPOS/php-mpos/blob/next/public/.htaccess'>.htaccess</a>";
$notice[] = "You don't seem to have a .htaccess in your public folder, if you're using apache set it up $htaccess_link";
$notice[] = "You don't seem to have a .htaccess in your public folder, if you're using Apache set it up: $htaccess_link";
}

// check if we can write templates/cache and templates/compile -> error
if (!is_writable(THEME_DIR.'/cache')) {
$error[] = "templates/cache folder is not writable for uid {$apache_user['name']}";
}
if (!is_writable(THEME_DIR.'/compile')) {
$error[] = "templates/compile folder is not writable for uid {$apache_user['name']}";
}

// check if we can write the config files, we should NOT be able to -> error
if (is_writable(INCLUDE_DIR.'/config/global.inc.php') || is_writable(INCLUDE_DIR.'/config/global.inc.dist.php') ||
is_writable(INCLUDE_DIR.'/config/security.inc.php') || is_writable(INCLUDE_DIR.'/config/security.inc.dist.php')) {
$error[] = "Your config files <b>SHOULD NOT be writable to this user</b>!";
}

// check if daemon can connect -> error
try {
if ($bitcoin->can_connect() !== true) {
Expand All @@ -76,7 +82,7 @@
if (!$bitcoin->validateaddress($config['coldwallet']['address']))
$error[] = "Your cold wallet address is <u>SET and INVALID</u>";
}

// check if there is more than one account set on wallet
$accounts = $bitcoin->listaccounts();
if (count($accounts) > 1 && $accounts[''] <= 0) {
Expand All @@ -85,34 +91,30 @@
}
} catch (Exception $e) {
}
// if database connection fails -> error
$db_connect = new mysqli($config['db']['host'], $config['db']['user'], $config['db']['pass'], $config['db']['name'], $config['db']['port']);
if (mysqli_connect_errno() || !array_key_exists('client_info', $db_connect)) {
$error[] = "Unable to connect to mysql using provided credentials";
}
// check anti DOS protection, we need memcache for that
if ($config['mc_antidos'] && !$config['memcache']['enabled']) {
$error[] = "mc_antidos is enabled and memcache is not, <u>memcache is required</u> to use this";
}

// poke stratum using gettingstarted details -> enotice
if (substr_count(strtolower(PHP_OS), 'nix') > 0) {
// unix *poke*
$socket = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (function_exists('socket_create')) {
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket !== false) {
$address = @gethostbyname($config['gettingstarted']['stratumurl']);
$result = @socket_connect($socket, $address, $config['gettingstarted']['stratumport']);
if ($result !== true) {
$enotice[] = "We tried to poke your Stratum server using config->gettingstarted details but it didn't respond";
$enotice[] = 'We tried to poke your Stratum server using your $config[\'gettingstarted\'] settings but it didn\'t respond';
}
$close = @socket_close($socket);
}
} else {
// mac/windows *poke*
if (! $fp = @fsockopen($config['gettingstarted']['stratumurl'],$config['gettingstarted']['stratumport'],$errCode,$errStr,1)) {
$enotice[] = "We tried to poke your Stratum server using config->gettingstarted details but it didn't respond";
// Connect via fsockopen as fallback
if (! $fp = @fsockopen($config['gettingstarted']['stratumurl'], $config['gettingstarted']['stratumport'], $errCode, $errStr, 1)) {
$enotice[] = 'We tried to poke your Stratum server using your $config[\'gettingstarted\'] settings but it didn\'t respond';
}
@fclose($fp);
}

// security checks
// salts too short -> notice, salts default -> error
if ((strlen($config['SALT']) < 24) || (strlen($config['SALTY']) < 24) || $config['SALT'] == 'PLEASEMAKEMESOMETHINGRANDOM' || $config['SALTY'] == 'THISSHOULDALSOBERRAANNDDOOM') {
Expand All @@ -122,7 +124,7 @@
$notice[] = "SALT or SALTY is too short, they should be more than 24 characters and changing them will require registering again";
}
}

// display the errors
foreach ($enotice as $en) {
$_SESSION['POPUP'][] = array('CONTENT' => $en, 'TYPE' => 'info');
Expand Down
21 changes: 21 additions & 0 deletions public/include/classes/setting.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,30 @@

class Setting extends Base {
protected $table = 'settings';
private $cache = array();

/**
* Fetch all values available and cache them in this class
* That way we don't fetch them from DB for each call
*/
public function createCache() {
if ($aSettings = $this->getAllAssoc()) {
foreach ($aSettings as $key => $aData) {
$this->cache[$aData['name']] = $aData['value'];
}
return true;
}
return false;
}

/**
* Fetch a value from our table
* @param name string Setting name
* @return value string Value
**/
public function getValue($name, $default="") {
// Try our class cache first
if (isset($this->cache[$name])) return $this->cache[$name];
$stmt = $this->mysqli->prepare("SELECT value FROM $this->table WHERE name = ? LIMIT 1");
if ($this->checkStmt($stmt) && $stmt->bind_param('s', $name) && $stmt->execute() && $result = $stmt->get_result()) {
if ($result->num_rows > 0) {
Expand All @@ -30,6 +47,8 @@ public function getValue($name, $default="") {
* @return bool
**/
public function setValue($name, $value) {
// Update local cache too
$this->cache[$name] = $value;
$stmt = $this->mysqli->prepare("
INSERT INTO $this->table (name, value)
VALUES (?, ?)
Expand All @@ -44,3 +63,5 @@ public function setValue($name, $value) {
$setting->setDebug($debug);
$setting->setMysql($mysqli);
$setting->setErrorCodes($aErrorCodes);
// Fill our class cache with data so we don't have to run SQL queries all the time
$setting->createCache();
2 changes: 1 addition & 1 deletion public/include/classes/statistics.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ public function getAllUserMiningStats($interval=180) {
share_id,
IF(difficulty = 0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty) AS difficulty,
username
FROM shares_archive
FROM " . $this->share->getArchiveTableName() . "
WHERE time > DATE_SUB(now(), INTERVAL ? SECOND) AND our_result = 'Y'
) AS t1
LEFT JOIN " . $this->user->getTableName() . " AS a
Expand Down
5 changes: 5 additions & 0 deletions public/include/classes/tools.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ private function getApiType($url) {
return 'btce';
} else if (preg_match('/cryptsy.com/', $url)) {
return 'cryptsy';
} else if (preg_match('/cryptorush.in/', $url)) {
return 'cryptorush';
}
$this->setErrorMessage("API URL unknown");
return false;
Expand Down Expand Up @@ -84,6 +86,9 @@ public function getPrice() {
case 'cryptsy':
return @$aData['return']['markets'][$strCurrency]['lasttradeprice'];
break;
case 'cryptorush':
return @$aData["$strCurrency/" . $this->config['price']['target']]['last_trade'];
break;
}
} else {
$this->setErrorMessage("Got an invalid response from ticker API");
Expand Down
Loading