Permalink
Browse files

NOMP CLI gives replies now. Profit switching transitioned to using CL…

…I port rather than old profitListener port.
  • Loading branch information...
zone117x committed Apr 28, 2014
1 parent 52108e3 commit 66d7640c9b035600c8a39f395bb939369c25820c
Showing with 146 additions and 132 deletions.
  1. +5 −2 README.md
  2. +95 −47 init.js
  3. +5 −3 libs/cliListener.js
  4. +1 −25 libs/mposCompatibility.js
  5. +1 −19 libs/poolWorker.js
  6. +39 −35 libs/profitSwitch.js
  7. +0 −1 scripts/cli.js
@@ -45,7 +45,8 @@ coins at once. The pools use clustering to load balance across multiple CPU core
* For reward/payment processing, shares are inserted into Redis (a fast NoSQL key/value store). The PROP (proportional)
reward system is used with [Redis Transactions](http://redis.io/topics/transactions) for secure and super speedy payouts.
Each and every share will be rewarded - even for rounds resulting in orphaned blocks.
There is zero risk to the pool operator. Shares from rounds resulting in orphaned blocks will be merged into share in the
current round so that each and every share will be rewarded
* This portal does not have user accounts/logins/registrations. Instead, miners simply use their coin address for stratum
authentication. A minimalistic HTML5 front-end connects to the portals statistics API to display stats from from each
@@ -108,10 +109,12 @@ If your pool uses NOMP let us know and we will list your website here.
* http://teamdoge.com
* http://miningwith.us
* http://kryptochaos.com
* http://pool.uberpools.org
* http://uberpools.org
* http://onebtcplace.com
* http://minr.es
* http://mining.theminingpools.com
* http://www.omargpools.ca/pools.html
* http://pool.trademybit.com/
Usage
=====
142 init.js
@@ -22,6 +22,7 @@ if (!fs.existsSync('config.json')){
}
var portalConfig = JSON.parse(JSON.minify(fs.readFileSync("config.json", {encoding: 'utf8'})));
var poolConfigs;
var logger = new PoolLogger({
@@ -156,7 +157,7 @@ var buildPoolConfigs = function(){
var spawnPoolWorkers = function(portalConfig, poolConfigs){
var spawnPoolWorkers = function(){
Object.keys(poolConfigs).forEach(function(coin){
var p = poolConfigs[coin];
@@ -179,9 +180,6 @@ var spawnPoolWorkers = function(portalConfig, poolConfigs){
return;
}
for (var p in poolConfigs){
}
var serializedConfigs = JSON.stringify(poolConfigs);
@@ -238,61 +236,111 @@ var spawnPoolWorkers = function(portalConfig, poolConfigs){
};
var startCliListener = function(cliPort){
var startCliListener = function(){
var cliPort = portalConfig.cliPort;
var listener = new CliListener(cliPort);
listener.on('log', function(text){
logger.debug('Master', 'CLI', text);
}).on('command', function(command, params, options){
}).on('command', function(command, params, options, reply){
switch(command){
case 'blocknotify':
Object.keys(cluster.workers).forEach(function(id) {
cluster.workers[id].send({type: 'blocknotify', coin: params[0], hash: params[1]});
});
reply('Pool workers notified');
break;
case 'coinswitch':
Object.keys(cluster.workers).forEach(function(id) {
cluster.workers[id].send({type: 'coinswitch', switchName: params[0], coin: params[1] });
});
processCoinSwitchCommand(params, options, reply);
break;
case 'restartpool':
case 'reloadpool':
Object.keys(cluster.workers).forEach(function(id) {
cluster.workers[id].send({type: 'restartpool', coin: params[0] });
cluster.workers[id].send({type: 'reloadpool', coin: params[0] });
});
reply('reloaded pool ' + params[0]);
break;
default:
reply('unrecognized command "' + command + '"');
break;
}
console.log('command: ' + JSON.stringify([command, params, options]));
}).start();
};
/*
//
// Receives authenticated events from coin switch listener and triggers proxy
// to swtich to a new coin.
//
var startCoinswitchListener = function(portalConfig){
var listener = new CoinswitchListener(portalConfig.coinSwitchListener);
listener.on('log', function(text){
logger.debug('Master', 'Coinswitch', text);
});
listener.on('switchcoin', function(message){
var ipcMessage = {type:'blocknotify', coin: message.coin, hash: message.hash};
Object.keys(cluster.workers).forEach(function(id) {
cluster.workers[id].send(ipcMessage);
});
var ipcMessage = {
type:'coinswitch',
coin: message.coin
};
Object.keys(cluster.workers).forEach(function(id) {
cluster.workers[id].send(ipcMessage);
var processCoinSwitchCommand = function(params, options, reply){
var logSystem = 'CLI';
var logComponent = 'coinswitch';
var replyError = function(msg){
reply(msg);
logger.error(logSystem, logComponent, msg);
};
if (!params[0]) {
replyError('Coin name required');
return;
}
if (!params[1] && !options.algorithm){
replyError('If switch key is not provided then algorithm options must be specified');
return;
}
else if (params[1] && !portalConfig.switching[params[1]]){
replyError('Switch key not recognized: ' + params[1]);
return;
}
else if (options.algorithm && !Object.keys(portalConfig.switching).filter(function(s){
return portalConfig.switching[s].algorithm === options.algorithm;
})[0]){
replyError('No switching options contain the algorithm ' + options.algorithm);
return;
}
var messageCoin = params[0].toLowerCase();
var newCoin = Object.keys(poolConfigs).filter(function(p){
return p.toLowerCase() === messageCoin;
})[0];
if (!newCoin){
replyError('Switch message to coin that is not recognized: ' + messageCoin);
return;
}
var switchNames = [];
if (params[1]) {
switchNames.push(params[1]);
}
else{
for (var name in portalConfig.switching){
if (portalConfig.switching[name].enabled && portalConfig.switching[name].algorithm === options.algorithm)
switchNames.push(name);
}
}
switchNames.forEach(function(name){
if (poolConfigs[newCoin].coin.algorithm !== portalConfig.switching[name].algorithm){
replyError('Cannot switch a '
+ portalConfig.switching[name].algorithm
+ ' algo pool to coin ' + newCoin + ' with ' + poolConfigs[newCoin].coin.algorithm + ' algo');
return;
}
Object.keys(cluster.workers).forEach(function (id) {
cluster.workers[id].send({type: 'coinswitch', coin: newCoin, switchName: name });
});
});
listener.start();
reply('Switch message sent to pool workers');
};
*/
var startRedisBlockListener = function(portalConfig){
var startRedisBlockListener = function(){
//block notify options
//setup block notify here and use IPC to tell appropriate pools
@@ -311,7 +359,7 @@ var startRedisBlockListener = function(portalConfig){
};
var startPaymentProcessor = function(poolConfigs){
var startPaymentProcessor = function(){
var enabledForAny = false;
for (var pool in poolConfigs){
@@ -339,7 +387,7 @@ var startPaymentProcessor = function(poolConfigs){
};
var startWebsite = function(portalConfig, poolConfigs){
var startWebsite = function(){
if (!portalConfig.website.enabled) return;
@@ -357,7 +405,7 @@ var startWebsite = function(portalConfig, poolConfigs){
};
var startProfitSwitch = function(portalConfig, poolConfigs){
var startProfitSwitch = function(){
if (!portalConfig.profitSwitch || !portalConfig.profitSwitch.enabled){
//logger.error('Master', 'Profit', 'Profit auto switching disabled');
@@ -381,18 +429,18 @@ var startProfitSwitch = function(portalConfig, poolConfigs){
(function init(){
var poolConfigs = buildPoolConfigs();
poolConfigs = buildPoolConfigs();
spawnPoolWorkers(portalConfig, poolConfigs);
spawnPoolWorkers();
startPaymentProcessor(poolConfigs);
startPaymentProcessor();
startRedisBlockListener(portalConfig);
startRedisBlockListener();
startWebsite(portalConfig, poolConfigs);
startWebsite();
startProfitSwitch(portalConfig, poolConfigs);
startProfitSwitch();
startCliListener(portalConfig.cliPort);
startCliListener();
})();
@@ -18,12 +18,14 @@ var listener = module.exports = function listener(port){
c.on('data', function (d) {
data += d;
if (data.slice(-1) === '\n') {
c.end();
var message = JSON.parse(data);
_this.emit('command', message.command, message.params, message.options, function(message){
c.end(message);
});
}
});
c.on('end', function () {
var message = JSON.parse(data);
_this.emit('command', message.command, message.params, message.options);
});
}
catch(e){
@@ -5,7 +5,7 @@ module.exports = function(logger, poolConfig){
var mposConfig = poolConfig.shareProcessing.mpos;
var coin = poolConfig.coin.name;
//var connection;
var connection;
var logIdentify = 'MySQL';
@@ -21,30 +21,6 @@ module.exports = function(logger, poolConfig){
database: mposConfig.database
});
/*connection = mysql.createConnection({
host: mposConfig.host,
port: mposConfig.port,
user: mposConfig.user,
password: mposConfig.password,
database: mposConfig.database
});
connection.connect(function(err){
if (err)
logger.error(logIdentify, logComponent, 'Could not connect to mysql database: ' + JSON.stringify(err))
else{
logger.debug(logIdentify, logComponent, 'Successful connection to MySQL database');
}
});
connection.on('error', function(err){
if(err.code === 'PROTOCOL_CONNECTION_LOST') {
logger.warning(logIdentify, logComponent, 'Lost connection to MySQL database, attempting reconnection...');
connect();
}
else{
logger.error(logIdentify, logComponent, 'Database error: ' + JSON.stringify(err))
}
});*/
}
connect();
@@ -50,29 +50,11 @@ module.exports = function(logger){
var logSubCat = 'Thread ' + (parseInt(forkId) + 1);
var switchName = message.switchName;
if (!portalConfig.switching[switchName]) {
logger.error(logSystem, logComponent, logSubCat, 'Switching key not recognized: ' + switchName);
}
var messageCoin = message.coin.toLowerCase();
var newCoin = Object.keys(pools).filter(function(p){
return p.toLowerCase() === messageCoin;
})[0];
if (!newCoin){
logger.error(logSystem, logComponent, logSubCat, 'Switch message to coin that is not recognized: ' + messageCoin);
break;
}
var newCoin = message.coin;
var algo = poolConfigs[newCoin].coin.algorithm;
if (algo !== proxySwitch[switchName].algorithm){
logger.error(logSystem, logComponent, logSubCat, 'Cannot switch a '
+ proxySwitch[switchName].algorithm
+ ' algo pool to coin ' + newCoin + ' with ' + algo + ' algo');
break;
}
var newPool = pools[newCoin];
var oldCoin = proxySwitch[switchName].currentPool;
var oldPool = pools[oldCoin];
Oops, something went wrong.

0 comments on commit 66d7640

Please sign in to comment.