Skip to content

Commit

Permalink
NOMP CLI gives replies now. Profit switching transitioned to using CL…
Browse files Browse the repository at this point in the history
…I port rather than old profitListener port.
  • Loading branch information
zone117x committed Apr 28, 2014
1 parent 52108e3 commit 66d7640
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 132 deletions.
7 changes: 5 additions & 2 deletions README.md
Expand Up @@ -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
Expand Down Expand Up @@ -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
=====
Expand Down
142 changes: 95 additions & 47 deletions init.js
Expand Up @@ -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({
Expand Down Expand Up @@ -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];
Expand All @@ -179,9 +180,6 @@ var spawnPoolWorkers = function(portalConfig, poolConfigs){
return;
}

for (var p in poolConfigs){

}

var serializedConfigs = JSON.stringify(poolConfigs);

Expand Down Expand Up @@ -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

Expand All @@ -311,7 +359,7 @@ var startRedisBlockListener = function(portalConfig){
};


var startPaymentProcessor = function(poolConfigs){
var startPaymentProcessor = function(){

var enabledForAny = false;
for (var pool in poolConfigs){
Expand Down Expand Up @@ -339,7 +387,7 @@ var startPaymentProcessor = function(poolConfigs){
};


var startWebsite = function(portalConfig, poolConfigs){
var startWebsite = function(){

if (!portalConfig.website.enabled) return;

Expand All @@ -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');
Expand All @@ -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();

})();
8 changes: 5 additions & 3 deletions libs/cliListener.js
Expand Up @@ -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){
Expand Down
26 changes: 1 addition & 25 deletions libs/mposCompatibility.js
Expand Up @@ -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';
Expand All @@ -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();
Expand Down
20 changes: 1 addition & 19 deletions libs/poolWorker.js
Expand Up @@ -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];
Expand Down

0 comments on commit 66d7640

Please sign in to comment.