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');
|
|
|
|
|
|
|
|
module.exports = function(logger){
|
|
|
|
|
|
|
|
|
|
|
|
var logDebug = logger.logDebug;
|
|
|
|
var logWarning = logger.logWarning;
|
|
|
|
var logError = logger.logError;
|
|
|
|
|
|
|
|
|
|
|
|
var poolConfigs = JSON.parse(process.env.pools);
|
|
|
|
var fork = process.env.fork;
|
|
|
|
|
|
|
|
var pools = [];
|
|
|
|
|
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':
|
|
|
|
for (var i = 0; i < pools.length; i++){
|
|
|
|
if (pools[i].options.coin.name.toLowerCase() === message.coin.toLowerCase()){
|
|
|
|
pools[i].processBlockNotify(message.hash)
|
|
|
|
return;
|
|
|
|
}
|
2014-03-01 17:19:10 -08:00
|
|
|
}
|
2014-03-04 12:24:02 -08:00
|
|
|
break;
|
|
|
|
case 'mposAuth':
|
|
|
|
var callbackId = message.callbackId;
|
2014-03-04 13:58:00 -08:00
|
|
|
if (callbackId in mposAuthCallbacks) {
|
2014-03-04 12:24:02 -08:00
|
|
|
mposAuthCallbacks[callbackId](message.authorized);
|
2014-03-04 13:58:00 -08:00
|
|
|
}
|
2014-03-04 12:24:02 -08:00
|
|
|
break;
|
2014-03-01 17:19:10 -08:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2014-03-04 12:24:02 -08:00
|
|
|
var mposAuthCallbacks = {};
|
|
|
|
|
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-03 12:51:11 -08:00
|
|
|
var logIdentify = coin + ' (Fork ' + fork + ')';
|
2014-03-01 17:19:10 -08:00
|
|
|
|
|
|
|
var authorizeFN = function (ip, workerName, password, callback) {
|
|
|
|
// Default implementation just returns true
|
|
|
|
logDebug(logIdentify, 'client', "Authorize [" + ip + "] " + workerName + ":" + password);
|
2014-03-04 12:24:02 -08:00
|
|
|
|
|
|
|
var mposAuthLevel;
|
|
|
|
if (poolOptions.shareProcessing.mpos.enabled && (
|
|
|
|
(mposAuthLevel = poolOptions.shareProcessing.mpos.stratumAuth) === 'worker' ||
|
|
|
|
mposAuthLevel === 'password'
|
|
|
|
)){
|
|
|
|
var callbackId = coin + workerName + password + Date.now();
|
|
|
|
var authTimeout = setTimeout(function(){
|
|
|
|
if (!(callbackId in mposAuthCallbacks))
|
|
|
|
return;
|
|
|
|
callback({
|
|
|
|
error: null,
|
|
|
|
authorized: false,
|
|
|
|
disconnect: false
|
|
|
|
});
|
|
|
|
delete mposAuthCallbacks[callbackId];
|
|
|
|
}, 30000);
|
|
|
|
mposAuthCallbacks[callbackId] = function(authorized){
|
|
|
|
callback({
|
|
|
|
error: null,
|
|
|
|
authorized: authorized,
|
|
|
|
disconnect: false
|
|
|
|
});
|
|
|
|
delete mposAuthCallbacks[callbackId];
|
|
|
|
clearTimeout(authTimeout);
|
|
|
|
};
|
|
|
|
process.send({
|
2014-03-04 14:35:43 -08:00
|
|
|
type : 'mposAuth',
|
|
|
|
coin : poolOptions.coin.name,
|
|
|
|
callbackId : callbackId,
|
|
|
|
workerId : cluster.worker.id,
|
|
|
|
workerName : workerName,
|
|
|
|
password : password,
|
|
|
|
authLevel : mposAuthLevel
|
2014-03-04 12:24:02 -08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
else{
|
2014-03-04 14:35:43 -08:00
|
|
|
// if we're here than it means we're on stratumAuth: "none" or something unrecognized by the system!
|
2014-03-04 12:24:02 -08:00
|
|
|
callback({
|
|
|
|
error: null,
|
|
|
|
authorized: true,
|
|
|
|
disconnect: false
|
|
|
|
});
|
|
|
|
}
|
2014-03-01 17:19:10 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
var pool = Stratum.createPool(poolOptions, authorizeFN);
|
2014-03-04 13:58:00 -08:00
|
|
|
pool.on('share', function(isValidShare, isValidBlock, data, blockHex){
|
2014-03-01 17:19:10 -08:00
|
|
|
|
|
|
|
var shareData = JSON.stringify(data);
|
|
|
|
|
|
|
|
if (data.solution && !isValidBlock){
|
|
|
|
logDebug(logIdentify, 'client', 'We thought a block solution was found but it was rejected by the daemon, share data: ' + shareData);
|
|
|
|
}
|
|
|
|
else if (!isValidShare){
|
|
|
|
logDebug(logIdentify, 'client', 'Invalid share submitted, share data: ' + shareData)
|
|
|
|
}
|
|
|
|
|
|
|
|
logDebug(logIdentify, 'client', 'Valid share submitted, share data: ' + shareData);
|
2014-03-03 12:51:11 -08:00
|
|
|
process.send({
|
2014-03-04 14:35:43 -08:00
|
|
|
type : 'share',
|
|
|
|
share : data,
|
|
|
|
coin : poolOptions.coin.name,
|
|
|
|
isValidShare : isValidShare,
|
|
|
|
isValidBlock : isValidBlock,
|
|
|
|
solution : blockHex // blockHex is undefined is this was not a valid block.
|
2014-03-03 12:51:11 -08:00
|
|
|
});
|
2014-03-01 17:19:10 -08:00
|
|
|
|
|
|
|
if (isValidBlock){
|
|
|
|
logDebug(logIdentify, 'client', 'Block found, solution: ' + shareData.solution);
|
|
|
|
process.send({
|
2014-03-04 14:35:43 -08:00
|
|
|
type : 'block',
|
|
|
|
share : data,
|
|
|
|
coin : poolOptions.coin.name
|
2014-03-01 17:19:10 -08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2014-03-04 00:33:55 -08:00
|
|
|
}).on('difficultyUpdate', function(workerName, diff){
|
|
|
|
if (poolOptions.shareProcessing.mpos.enabled){
|
|
|
|
process.send({
|
2014-03-04 14:35:43 -08:00
|
|
|
type : 'difficultyUpdate',
|
|
|
|
workerName : workerName,
|
|
|
|
diff : diff,
|
|
|
|
coin : poolOptions.coin.name
|
2014-03-04 00:33:55 -08:00
|
|
|
});
|
|
|
|
}
|
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') {
|
|
|
|
logDebug(logIdentify, logKey, logText);
|
|
|
|
} else if (severity == 'warning') {
|
|
|
|
logWarning(logIdentify, logKey, logText);
|
|
|
|
} else if (severity == 'error') {
|
|
|
|
logError(logIdentify, logKey, logText);
|
|
|
|
}
|
|
|
|
});
|
2014-03-01 17:19:10 -08:00
|
|
|
pool.start();
|
|
|
|
pools.push(pool);
|
|
|
|
});
|
|
|
|
};
|