2014-03-04 12:24:02 -08:00
|
|
|
var cluster = require('cluster');
|
|
|
|
|
2014-03-01 17:19:10 -08:00
|
|
|
var Stratum = require('stratum-pool');
|
|
|
|
|
2014-03-05 14:10:50 -08:00
|
|
|
var MposCompatibility = require('./mposCompatibility.js');
|
|
|
|
var ShareProcessor = require('./shareProcessor.js');
|
2014-03-01 17:19:10 -08:00
|
|
|
|
2014-03-05 14:10:50 -08:00
|
|
|
module.exports = function(logger){
|
2014-03-01 17:19:10 -08:00
|
|
|
|
|
|
|
|
|
|
|
var poolConfigs = JSON.parse(process.env.pools);
|
2014-03-05 14:10:50 -08:00
|
|
|
var forkId = process.env.forkId;
|
2014-03-01 17:19:10 -08:00
|
|
|
|
2014-03-05 14:10:50 -08:00
|
|
|
var pools = {};
|
2014-03-01 17:19:10 -08:00
|
|
|
|
2014-03-04 12:24:02 -08:00
|
|
|
//Handle messages from master process sent via IPC
|
2014-03-01 17:19:10 -08:00
|
|
|
process.on('message', function(message) {
|
2014-03-04 12:24:02 -08:00
|
|
|
switch(message.type){
|
|
|
|
case 'blocknotify':
|
2014-03-05 14:10:50 -08:00
|
|
|
var pool = pools[message.coin.toLowerCase()]
|
|
|
|
if (pool) pool.processBlockNotify(message.hash)
|
2014-03-04 12:24:02 -08:00
|
|
|
break;
|
2014-03-01 17:19:10 -08:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2014-03-03 12:51:11 -08:00
|
|
|
Object.keys(poolConfigs).forEach(function(coin) {
|
2014-03-01 17:19:10 -08:00
|
|
|
|
2014-03-03 12:51:11 -08:00
|
|
|
var poolOptions = poolConfigs[coin];
|
2014-03-01 17:19:10 -08:00
|
|
|
|
2014-03-05 14:10:50 -08:00
|
|
|
var logIdentify = coin + ' (Fork ' + forkId + ')';
|
|
|
|
|
|
|
|
var poolLogger = {
|
|
|
|
debug: function(key, text){
|
|
|
|
logger.logDebug(logIdentify, key, text);
|
|
|
|
},
|
|
|
|
warning: function(key, text){
|
|
|
|
logger.logWarning(logIdentify, key, text);
|
|
|
|
},
|
|
|
|
error: function(key, text){
|
|
|
|
logger.logError(logIdentify, key, text);
|
|
|
|
}
|
|
|
|
};
|
2014-03-01 17:19:10 -08:00
|
|
|
|
2014-03-05 14:10:50 -08:00
|
|
|
var handlers = {
|
|
|
|
auth: function(){},
|
|
|
|
share: function(){},
|
|
|
|
diff: function(){}
|
|
|
|
};
|
|
|
|
|
|
|
|
var shareProcessing = poolOptions.shareProcessing;
|
|
|
|
|
|
|
|
//Functions required for MPOS compatibility
|
|
|
|
if (shareProcessing.mpos && shareProcessing.mpos.enabled){
|
|
|
|
var mposCompat = new MposCompatibility(poolLogger, poolOptions)
|
|
|
|
|
|
|
|
handlers.auth = function(workerName, password, authCallback){
|
|
|
|
mposCompat.handleAuth(workerName, password, authCallback);
|
|
|
|
};
|
|
|
|
|
|
|
|
handlers.share = function(isValidShare, isValidBlock, data){
|
|
|
|
mposCompat.handleShare(isValidShare, isValidBlock, data);
|
|
|
|
};
|
|
|
|
|
|
|
|
handlers.diff = function(workerName, diff){
|
|
|
|
mposCompat.handleDifficultyUpdate(workerName, diff);
|
2014-03-04 12:24:02 -08:00
|
|
|
}
|
2014-03-05 14:10:50 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
//Functions required for internal payment processing
|
|
|
|
else if (shareProcessing.internal && shareProcessing.internal.enabled){
|
|
|
|
|
|
|
|
var shareProcessor = new ShareProcessor(poolLogger, poolOptions)
|
|
|
|
|
|
|
|
handlers.auth = function(workerName, password, authCallback){
|
|
|
|
authCallback({
|
2014-03-04 12:24:02 -08:00
|
|
|
error: null,
|
|
|
|
authorized: true,
|
|
|
|
disconnect: false
|
|
|
|
});
|
2014-03-05 14:10:50 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
handlers.share = function(isValidShare, isValidBlock, data){
|
|
|
|
shareProcessor.handleShare(isValidShare, isValidBlock, data);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
var authorizeFN = function (ip, workerName, password, callback) {
|
|
|
|
handlers.auth(workerName, password, function(authorized){
|
|
|
|
|
|
|
|
var authString = authorized ? 'Authorized' : 'Unauthorized ';
|
|
|
|
|
2014-03-05 14:31:32 -08:00
|
|
|
poolLogger.debug('client', authString + ' [' + ip + '] ' + workerName + ':' + password);
|
2014-03-05 14:10:50 -08:00
|
|
|
callback({
|
|
|
|
error: null,
|
|
|
|
authorized: authorized,
|
|
|
|
disconnect: false
|
|
|
|
});
|
|
|
|
});
|
2014-03-01 17:19:10 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
var pool = Stratum.createPool(poolOptions, authorizeFN);
|
2014-03-05 14:10:50 -08:00
|
|
|
pool.on('share', function(isValidShare, isValidBlock, data){
|
2014-03-01 17:19:10 -08:00
|
|
|
|
|
|
|
var shareData = JSON.stringify(data);
|
|
|
|
|
2014-03-05 14:10:50 -08:00
|
|
|
if (data.solution && !isValidBlock)
|
2014-03-06 12:46:01 -08:00
|
|
|
poolLogger.debug('client', 'We thought a block solution was found but it was rejected by the daemon, share data: ' + data);
|
2014-03-05 14:10:50 -08:00
|
|
|
else if (isValidBlock)
|
2014-03-06 12:46:01 -08:00
|
|
|
poolLogger.debug('client', 'Block found, solution: ' + data.solution);
|
2014-03-01 17:19:10 -08:00
|
|
|
|
2014-03-05 14:10:50 -08:00
|
|
|
if (isValidShare)
|
2014-03-06 12:46:01 -08:00
|
|
|
poolLogger.debug('client', 'Valid share submitted, share data: ' + data);
|
2014-03-05 14:10:50 -08:00
|
|
|
else if (!isValidShare)
|
2014-03-06 12:46:01 -08:00
|
|
|
poolLogger.debug('client', 'Invalid share submitted, share data: ' + data)
|
2014-03-05 14:10:50 -08:00
|
|
|
|
|
|
|
|
|
|
|
handlers.share(isValidShare, isValidBlock, data)
|
2014-03-01 17:19:10 -08:00
|
|
|
|
|
|
|
|
2014-03-04 00:33:55 -08:00
|
|
|
}).on('difficultyUpdate', function(workerName, diff){
|
2014-03-05 14:10:50 -08:00
|
|
|
handlers.diff(workerName, diff);
|
2014-03-01 17:19:10 -08:00
|
|
|
}).on('log', function(severity, logKey, logText) {
|
2014-03-04 00:33:55 -08:00
|
|
|
if (severity == 'debug') {
|
2014-03-05 14:10:50 -08:00
|
|
|
poolLogger.debug(logKey, logText);
|
2014-03-04 00:33:55 -08:00
|
|
|
} else if (severity == 'warning') {
|
2014-03-05 14:10:50 -08:00
|
|
|
poolLogger.warning(logKey, logText);
|
2014-03-04 00:33:55 -08:00
|
|
|
} else if (severity == 'error') {
|
2014-03-05 14:10:50 -08:00
|
|
|
poolLogger.error(logKey, logText);
|
2014-03-04 00:33:55 -08:00
|
|
|
}
|
|
|
|
});
|
2014-03-01 17:19:10 -08:00
|
|
|
pool.start();
|
2014-03-05 14:10:50 -08:00
|
|
|
pools[poolOptions.coin.name.toLowerCase()] = pool;
|
2014-03-01 17:19:10 -08:00
|
|
|
});
|
|
|
|
};
|