NOMP CLI gives replies now. Profit switching transitioned to using CLI port rather than old profitListener port.
This commit is contained in:
parent
52108e3b7a
commit
66d7640c9b
|
@ -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)
|
* 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.
|
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
|
* 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
|
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://teamdoge.com
|
||||||
* http://miningwith.us
|
* http://miningwith.us
|
||||||
* http://kryptochaos.com
|
* http://kryptochaos.com
|
||||||
* http://pool.uberpools.org
|
* http://uberpools.org
|
||||||
* http://onebtcplace.com
|
* http://onebtcplace.com
|
||||||
* http://minr.es
|
* http://minr.es
|
||||||
* http://mining.theminingpools.com
|
* http://mining.theminingpools.com
|
||||||
|
* http://www.omargpools.ca/pools.html
|
||||||
|
* http://pool.trademybit.com/
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
=====
|
=====
|
||||||
|
|
148
init.js
148
init.js
|
@ -22,6 +22,7 @@ if (!fs.existsSync('config.json')){
|
||||||
}
|
}
|
||||||
|
|
||||||
var portalConfig = JSON.parse(JSON.minify(fs.readFileSync("config.json", {encoding: 'utf8'})));
|
var portalConfig = JSON.parse(JSON.minify(fs.readFileSync("config.json", {encoding: 'utf8'})));
|
||||||
|
var poolConfigs;
|
||||||
|
|
||||||
|
|
||||||
var logger = new PoolLogger({
|
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){
|
Object.keys(poolConfigs).forEach(function(coin){
|
||||||
var p = poolConfigs[coin];
|
var p = poolConfigs[coin];
|
||||||
|
@ -179,9 +180,6 @@ var spawnPoolWorkers = function(portalConfig, poolConfigs){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var p in poolConfigs){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
var serializedConfigs = JSON.stringify(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);
|
var listener = new CliListener(cliPort);
|
||||||
listener.on('log', function(text){
|
listener.on('log', function(text){
|
||||||
logger.debug('Master', 'CLI', text);
|
logger.debug('Master', 'CLI', text);
|
||||||
}).on('command', function(command, params, options){
|
}).on('command', function(command, params, options, reply){
|
||||||
|
|
||||||
switch(command){
|
switch(command){
|
||||||
case 'blocknotify':
|
case 'blocknotify':
|
||||||
Object.keys(cluster.workers).forEach(function(id) {
|
Object.keys(cluster.workers).forEach(function(id) {
|
||||||
cluster.workers[id].send({type: 'blocknotify', coin: params[0], hash: params[1]});
|
cluster.workers[id].send({type: 'blocknotify', coin: params[0], hash: params[1]});
|
||||||
});
|
});
|
||||||
|
reply('Pool workers notified');
|
||||||
break;
|
break;
|
||||||
case 'coinswitch':
|
case 'coinswitch':
|
||||||
Object.keys(cluster.workers).forEach(function(id) {
|
processCoinSwitchCommand(params, options, reply);
|
||||||
cluster.workers[id].send({type: 'coinswitch', switchName: params[0], coin: params[1] });
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case 'restartpool':
|
case 'reloadpool':
|
||||||
Object.keys(cluster.workers).forEach(function(id) {
|
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();
|
}).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);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
listener.start();
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
var startRedisBlockListener = function(portalConfig){
|
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 });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
reply('Switch message sent to pool workers');
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var startRedisBlockListener = function(){
|
||||||
//block notify options
|
//block notify options
|
||||||
//setup block notify here and use IPC to tell appropriate pools
|
//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;
|
var enabledForAny = false;
|
||||||
for (var pool in poolConfigs){
|
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;
|
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){
|
if (!portalConfig.profitSwitch || !portalConfig.profitSwitch.enabled){
|
||||||
//logger.error('Master', 'Profit', 'Profit auto switching disabled');
|
//logger.error('Master', 'Profit', 'Profit auto switching disabled');
|
||||||
|
@ -381,18 +429,18 @@ var startProfitSwitch = function(portalConfig, poolConfigs){
|
||||||
|
|
||||||
(function init(){
|
(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) {
|
c.on('data', function (d) {
|
||||||
data += d;
|
data += d;
|
||||||
if (data.slice(-1) === '\n') {
|
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 () {
|
c.on('end', function () {
|
||||||
var message = JSON.parse(data);
|
|
||||||
_this.emit('command', message.command, message.params, message.options);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch(e){
|
catch(e){
|
||||||
|
|
|
@ -5,7 +5,7 @@ module.exports = function(logger, poolConfig){
|
||||||
var mposConfig = poolConfig.shareProcessing.mpos;
|
var mposConfig = poolConfig.shareProcessing.mpos;
|
||||||
var coin = poolConfig.coin.name;
|
var coin = poolConfig.coin.name;
|
||||||
|
|
||||||
//var connection;
|
var connection;
|
||||||
|
|
||||||
|
|
||||||
var logIdentify = 'MySQL';
|
var logIdentify = 'MySQL';
|
||||||
|
@ -21,30 +21,6 @@ module.exports = function(logger, poolConfig){
|
||||||
database: mposConfig.database
|
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();
|
connect();
|
||||||
|
|
|
@ -50,29 +50,11 @@ module.exports = function(logger){
|
||||||
var logSubCat = 'Thread ' + (parseInt(forkId) + 1);
|
var logSubCat = 'Thread ' + (parseInt(forkId) + 1);
|
||||||
|
|
||||||
var switchName = message.switchName;
|
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 = message.coin;
|
||||||
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 algo = poolConfigs[newCoin].coin.algorithm;
|
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 newPool = pools[newCoin];
|
||||||
var oldCoin = proxySwitch[switchName].currentPool;
|
var oldCoin = proxySwitch[switchName].currentPool;
|
||||||
var oldPool = pools[oldCoin];
|
var oldPool = pools[oldCoin];
|
||||||
|
|
|
@ -420,31 +420,28 @@ module.exports = function(logger){
|
||||||
};
|
};
|
||||||
this.getDaemonInfoForCoin = function(symbol, cfg, callback){
|
this.getDaemonInfoForCoin = function(symbol, cfg, callback){
|
||||||
var daemon = new Stratum.daemon.interface([cfg]);
|
var daemon = new Stratum.daemon.interface([cfg]);
|
||||||
daemon.once('online', function(){
|
daemon.on('error', function(error){
|
||||||
daemon.cmd('getblocktemplate', [{"capabilities": [ "coinbasetxn", "workid", "coinbase/append" ]}], function(result){
|
|
||||||
if (result[0].error != null){
|
|
||||||
logger.error(logSystem, symbol, 'Error while reading daemon info: ' + JSON.stringify(result[0]));
|
|
||||||
callback(null); // fail gracefully for each coin
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var coinStatus = profitStatus[symbolToAlgorithmMap[symbol]][symbol];
|
|
||||||
var response = result[0].response;
|
|
||||||
|
|
||||||
// some shitcoins dont provide target, only bits, so we need to deal with both
|
|
||||||
var target = response.target ? bignum(response.target, 16) : util.bignumFromBitsHex(response.bits);
|
|
||||||
coinStatus.difficulty = parseFloat((diff1 / target.toNumber()).toFixed(9));
|
|
||||||
logger.debug(logSystem, symbol, 'difficulty is ' + coinStatus.difficulty);
|
|
||||||
|
|
||||||
coinStatus.reward = new Number(response.coinbasevalue / 100000000);
|
|
||||||
callback(null);
|
|
||||||
});
|
|
||||||
}).once('connectionFailed', function(error){
|
|
||||||
logger.error(logSystem, symbol, JSON.stringify(error));
|
|
||||||
callback(null); // fail gracefully for each coin
|
|
||||||
}).on('error', function(error){
|
|
||||||
logger.error(logSystem, symbol, JSON.stringify(error));
|
logger.error(logSystem, symbol, JSON.stringify(error));
|
||||||
callback(null); // fail gracefully for each coin
|
callback(null); // fail gracefully for each coin
|
||||||
}).init();
|
}).init();
|
||||||
|
|
||||||
|
daemon.cmd('getblocktemplate', [{"capabilities": [ "coinbasetxn", "workid", "coinbase/append" ]}], function(result) {
|
||||||
|
if (result[0].error != null) {
|
||||||
|
logger.error(logSystem, symbol, 'Error while reading daemon info: ' + JSON.stringify(result[0]));
|
||||||
|
callback(null); // fail gracefully for each coin
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var coinStatus = profitStatus[symbolToAlgorithmMap[symbol]][symbol];
|
||||||
|
var response = result[0].response;
|
||||||
|
|
||||||
|
// some shitcoins dont provide target, only bits, so we need to deal with both
|
||||||
|
var target = response.target ? bignum(response.target, 16) : util.bignumFromBitsHex(response.bits);
|
||||||
|
coinStatus.difficulty = parseFloat((diff1 / target.toNumber()).toFixed(9));
|
||||||
|
logger.debug(logSystem, symbol, 'difficulty is ' + coinStatus.difficulty);
|
||||||
|
|
||||||
|
coinStatus.reward = response.coinbasevalue / 100000000;
|
||||||
|
callback(null);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -453,8 +450,8 @@ module.exports = function(logger){
|
||||||
Object.keys(profitStatus).forEach(function(algo){
|
Object.keys(profitStatus).forEach(function(algo){
|
||||||
Object.keys(profitStatus[algo]).forEach(function(symbol){
|
Object.keys(profitStatus[algo]).forEach(function(symbol){
|
||||||
var coinStatus = profitStatus[symbolToAlgorithmMap[symbol]][symbol];
|
var coinStatus = profitStatus[symbolToAlgorithmMap[symbol]][symbol];
|
||||||
coinStatus.blocksPerMhPerHour = new Number(86400 / ((coinStatus.difficulty * Math.pow(2,32)) / (1 * 1000 * 1000)));
|
coinStatus.blocksPerMhPerHour = 86400 / ((coinStatus.difficulty * Math.pow(2,32)) / (1 * 1000 * 1000));
|
||||||
coinStatus.coinsPerMhPerHour = new Number(coinStatus.reward * coinStatus.blocksPerMhPerHour);
|
coinStatus.coinsPerMhPerHour = coinStatus.reward * coinStatus.blocksPerMhPerHour;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
callback(null);
|
callback(null);
|
||||||
|
@ -467,7 +464,7 @@ module.exports = function(logger){
|
||||||
|
|
||||||
var bestExchange;
|
var bestExchange;
|
||||||
var bestCoin;
|
var bestCoin;
|
||||||
var bestBtcPerMhPerHour = new Number(0);
|
var bestBtcPerMhPerHour = 0;
|
||||||
|
|
||||||
Object.keys(profitStatus[algo]).forEach(function(symbol) {
|
Object.keys(profitStatus[algo]).forEach(function(symbol) {
|
||||||
var coinStatus = profitStatus[algo][symbol];
|
var coinStatus = profitStatus[algo][symbol];
|
||||||
|
@ -475,7 +472,7 @@ module.exports = function(logger){
|
||||||
Object.keys(coinStatus.exchangeInfo).forEach(function(exchange){
|
Object.keys(coinStatus.exchangeInfo).forEach(function(exchange){
|
||||||
var exchangeData = coinStatus.exchangeInfo[exchange];
|
var exchangeData = coinStatus.exchangeInfo[exchange];
|
||||||
if (exchangeData.hasOwnProperty('BTC') && exchangeData['BTC'].hasOwnProperty('weightedBid')){
|
if (exchangeData.hasOwnProperty('BTC') && exchangeData['BTC'].hasOwnProperty('weightedBid')){
|
||||||
var btcPerMhPerHour = new Number(exchangeData['BTC'].weightedBid * coinStatus.coinsPerMhPerHour);
|
var btcPerMhPerHour = exchangeData['BTC'].weightedBid * coinStatus.coinsPerMhPerHour;
|
||||||
if (btcPerMhPerHour > bestBtcPerMhPerHour){
|
if (btcPerMhPerHour > bestBtcPerMhPerHour){
|
||||||
bestBtcPerMhPerHour = btcPerMhPerHour;
|
bestBtcPerMhPerHour = btcPerMhPerHour;
|
||||||
bestExchange = exchange;
|
bestExchange = exchange;
|
||||||
|
@ -485,7 +482,7 @@ module.exports = function(logger){
|
||||||
logger.debug(logSystem, 'CALC', 'BTC/' + symbol + ' on ' + exchange + ' with ' + coinStatus.btcPerMhPerHour.toFixed(8) + ' BTC/day per Mh/s');
|
logger.debug(logSystem, 'CALC', 'BTC/' + symbol + ' on ' + exchange + ' with ' + coinStatus.btcPerMhPerHour.toFixed(8) + ' BTC/day per Mh/s');
|
||||||
}
|
}
|
||||||
if (exchangeData.hasOwnProperty('LTC') && exchangeData['LTC'].hasOwnProperty('weightedBid')){
|
if (exchangeData.hasOwnProperty('LTC') && exchangeData['LTC'].hasOwnProperty('weightedBid')){
|
||||||
var btcPerMhPerHour = new Number((exchangeData['LTC'].weightedBid * coinStatus.coinsPerMhPerHour) * exchangeData['LTC'].ltcToBtc);
|
var btcPerMhPerHour = (exchangeData['LTC'].weightedBid * coinStatus.coinsPerMhPerHour) * exchangeData['LTC'].ltcToBtc;
|
||||||
if (btcPerMhPerHour > bestBtcPerMhPerHour){
|
if (btcPerMhPerHour > bestBtcPerMhPerHour){
|
||||||
bestBtcPerMhPerHour = btcPerMhPerHour;
|
bestBtcPerMhPerHour = btcPerMhPerHour;
|
||||||
bestExchange = exchange;
|
bestExchange = exchange;
|
||||||
|
@ -497,14 +494,21 @@ module.exports = function(logger){
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
logger.debug(logSystem, 'RESULT', 'Best coin for ' + algo + ' is ' + bestCoin + ' on ' + bestExchange + ' with ' + bestBtcPerMhPerHour.toFixed(8) + ' BTC/day per Mh/s');
|
logger.debug(logSystem, 'RESULT', 'Best coin for ' + algo + ' is ' + bestCoin + ' on ' + bestExchange + ' with ' + bestBtcPerMhPerHour.toFixed(8) + ' BTC/day per Mh/s');
|
||||||
if (portalConfig.coinSwitchListener.enabled){
|
|
||||||
var client = net.connect(portalConfig.coinSwitchListener.port, portalConfig.coinSwitchListener.host, function () {
|
|
||||||
client.write(JSON.stringify({
|
var client = net.connect(portalConfig.cliPort, function () {
|
||||||
password: portalConfig.coinSwitchListener.password,
|
client.write(JSON.stringify({
|
||||||
coin: bestCoin
|
command: 'coinswitch',
|
||||||
}) + '\n');
|
params: [bestCoin],
|
||||||
});
|
options: {algorithm: algo}
|
||||||
}
|
}) + '\n');
|
||||||
|
}).on('error', function(error){
|
||||||
|
if (error.code === 'ECONNREFUSED')
|
||||||
|
logger.error(logSystem, 'CLI', 'Could not connect to NOMP instance on port ' + portalConfig.cliPort);
|
||||||
|
else
|
||||||
|
logger.error(logSystem, 'CLI', 'Socket error ' + JSON.stringify(error));
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -34,5 +34,4 @@ var client = net.connect(options.port || defaultPort, options.host || defaultHos
|
||||||
}).on('data', function(data) {
|
}).on('data', function(data) {
|
||||||
console.log(data.toString());
|
console.log(data.toString());
|
||||||
}).on('close', function () {
|
}).on('close', function () {
|
||||||
|
|
||||||
});
|
});
|
Loading…
Reference in New Issue