Merge branch 'master' of https://github.com/zone117x/node-stratum-portal
This commit is contained in:
commit
818fd3385d
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
node_modules/
|
node_modules/
|
||||||
.idea/
|
.idea/
|
||||||
|
pool_configs/
|
||||||
48
config.json
48
config.json
@ -2,15 +2,57 @@
|
|||||||
"logLevel": "debug",
|
"logLevel": "debug",
|
||||||
"clustering": {
|
"clustering": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"forks": "auto"
|
"forks": "1"
|
||||||
},
|
},
|
||||||
"blockNotifyListener": {
|
"blockNotifyListener": {
|
||||||
"enabled": true,
|
"enabled": false,
|
||||||
"port": 8117,
|
"port": 8117,
|
||||||
"password": "test"
|
"password": "test"
|
||||||
},
|
},
|
||||||
"website": {
|
|
||||||
|
"redisBlockNotifyListener": {
|
||||||
|
"enabled" : false,
|
||||||
|
"redisPort" : 6379,
|
||||||
|
"redisHost" : "hostname",
|
||||||
|
"psubscribeKey" : "newblocks:*"
|
||||||
|
},
|
||||||
|
"proxy": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
|
"ports": {
|
||||||
|
"80": {
|
||||||
|
"diff": 32,
|
||||||
|
"varDiff": {
|
||||||
|
"minDiff" : 8,
|
||||||
|
"maxDiff" : 512,
|
||||||
|
"targetTime" : 15,
|
||||||
|
"retargetTime" : 90,
|
||||||
|
"variancePercent" : 30
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"6000": {
|
||||||
|
"diff": 32,
|
||||||
|
"varDiff": {
|
||||||
|
"minDiff" : 8,
|
||||||
|
"maxDiff" : 512,
|
||||||
|
"targetTime" : 15,
|
||||||
|
"retargetTime" : 90,
|
||||||
|
"variancePercent" : 30
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"8080": {
|
||||||
|
"diff": 32,
|
||||||
|
"varDiff": {
|
||||||
|
"minDiff" : 8,
|
||||||
|
"maxDiff" : 512,
|
||||||
|
"targetTime" : 15,
|
||||||
|
"retargetTime" : 90,
|
||||||
|
"variancePercent" : 30
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"website": {
|
||||||
|
"enabled": false,
|
||||||
"port": 80,
|
"port": 80,
|
||||||
"liveStats": true
|
"liveStats": true
|
||||||
}
|
}
|
||||||
|
|||||||
64
init.js
64
init.js
@ -3,19 +3,18 @@ var os = require('os');
|
|||||||
var cluster = require('cluster');
|
var cluster = require('cluster');
|
||||||
|
|
||||||
|
|
||||||
var posix = require('posix');
|
var posix = require('posix');
|
||||||
var PoolLogger = require('./libs/logUtil.js');
|
var PoolLogger = require('./libs/logUtil.js');
|
||||||
var BlocknotifyListener = require('./libs/blocknotifyListener.js');
|
var BlocknotifyListener = require('./libs/blocknotifyListener.js');
|
||||||
var WorkerListener = require('./libs/workerListener.js');
|
var RedisBlocknotifyListener = require('./libs/redisblocknotifyListener.js');
|
||||||
var PoolWorker = require('./libs/poolWorker.js');
|
var WorkerListener = require('./libs/workerListener.js');
|
||||||
var PaymentProcessor = require('./libs/paymentProcessor.js');
|
var PoolWorker = require('./libs/poolWorker.js');
|
||||||
var Website = require('./libs/website.js');
|
var PaymentProcessor = require('./libs/paymentProcessor.js');
|
||||||
|
var Website = require('./libs/website.js');
|
||||||
JSON.minify = JSON.minify || require("node-json-minify");
|
JSON.minify = JSON.minify || require("node-json-minify");
|
||||||
|
|
||||||
|
|
||||||
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 loggerInstance = new PoolLogger({
|
var loggerInstance = new PoolLogger({
|
||||||
logLevel: portalConfig.logLevel
|
logLevel: portalConfig.logLevel
|
||||||
@ -37,7 +36,7 @@ catch(e){
|
|||||||
|
|
||||||
|
|
||||||
if (cluster.isWorker){
|
if (cluster.isWorker){
|
||||||
|
|
||||||
switch(process.env.workerType){
|
switch(process.env.workerType){
|
||||||
case 'pool':
|
case 'pool':
|
||||||
new PoolWorker(loggerInstance);
|
new PoolWorker(loggerInstance);
|
||||||
@ -51,7 +50,18 @@ if (cluster.isWorker){
|
|||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
} /* else {
|
||||||
|
var coinNames = ['alphacoin','frankocoin','emerald','kittehcoin'];
|
||||||
|
var curIndex = 0;
|
||||||
|
setInterval(function () {
|
||||||
|
var newCoinName = coinNames[++curIndex % coinNames.length];
|
||||||
|
console.log("SWITCHING to "+newCoinName);
|
||||||
|
var ipcMessage = {type:'switch', coin: newCoinName};
|
||||||
|
Object.keys(cluster.workers).forEach(function(id) {
|
||||||
|
cluster.workers[id].send(ipcMessage);
|
||||||
|
});
|
||||||
|
}, 20000);
|
||||||
|
} */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -93,9 +103,10 @@ var spawnPoolWorkers = function(portalConfig, poolConfigs){
|
|||||||
|
|
||||||
var createPoolWorker = function(forkId){
|
var createPoolWorker = function(forkId){
|
||||||
var worker = cluster.fork({
|
var worker = cluster.fork({
|
||||||
workerType: 'pool',
|
workerType : 'pool',
|
||||||
forkId: forkId,
|
forkId : forkId,
|
||||||
pools: serializedConfigs
|
pools : serializedConfigs,
|
||||||
|
portalConfig : JSON.stringify(portalConfig),
|
||||||
});
|
});
|
||||||
worker.on('exit', function(code, signal){
|
worker.on('exit', function(code, signal){
|
||||||
logError('poolWorker', 'system', 'Fork ' + forkId + ' died, spawning replacement worker...');
|
logError('poolWorker', 'system', 'Fork ' + forkId + ' died, spawning replacement worker...');
|
||||||
@ -136,6 +147,21 @@ var startBlockListener = function(portalConfig){
|
|||||||
listener.start();
|
listener.start();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var startRedisBlockListener = function(portalConfig){
|
||||||
|
//block notify options
|
||||||
|
//setup block notify here and use IPC to tell appropriate pools
|
||||||
|
var listener = new RedisBlocknotifyListener(portalConfig.redisBlockNotifyListener);
|
||||||
|
listener.on('log', function(text){
|
||||||
|
logDebug('blocknotify', 'system', text);
|
||||||
|
}).on('hash', function (message) {
|
||||||
|
var ipcMessage = {type:'blocknotify', coin: message.coin, hash: message.hash};
|
||||||
|
Object.keys(cluster.workers).forEach(function(id) {
|
||||||
|
cluster.workers[id].send(ipcMessage);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
listener.start();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
var startPaymentProcessor = function(poolConfigs){
|
var startPaymentProcessor = function(poolConfigs){
|
||||||
var worker = cluster.fork({
|
var worker = cluster.fork({
|
||||||
@ -152,6 +178,8 @@ var startPaymentProcessor = function(poolConfigs){
|
|||||||
|
|
||||||
|
|
||||||
var startWebsite = function(portalConfig, poolConfigs){
|
var startWebsite = function(portalConfig, poolConfigs){
|
||||||
|
console.log(portalConfig.website);
|
||||||
|
|
||||||
if (!portalConfig.website.enabled) return;
|
if (!portalConfig.website.enabled) return;
|
||||||
|
|
||||||
var worker = cluster.fork({
|
var worker = cluster.fork({
|
||||||
@ -168,7 +196,6 @@ var startWebsite = function(portalConfig, poolConfigs){
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(function init(){
|
(function init(){
|
||||||
|
|
||||||
var poolConfigs = buildPoolConfigs();
|
var poolConfigs = buildPoolConfigs();
|
||||||
@ -179,8 +206,11 @@ var startWebsite = function(portalConfig, poolConfigs){
|
|||||||
|
|
||||||
startBlockListener(portalConfig);
|
startBlockListener(portalConfig);
|
||||||
|
|
||||||
|
startRedisBlockListener(portalConfig);
|
||||||
|
|
||||||
startWorkerListener(poolConfigs);
|
startWorkerListener(poolConfigs);
|
||||||
|
;
|
||||||
|
|
||||||
startWebsite(portalConfig, poolConfigs);
|
startWebsite(portalConfig, poolConfigs);
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
@ -53,12 +53,12 @@ var PoolLogger = function (configuration) {
|
|||||||
|
|
||||||
var desc = poolName ? '[' + poolName + '] ' : '';
|
var desc = poolName ? '[' + poolName + '] ' : '';
|
||||||
console.log(
|
console.log(
|
||||||
'\u001b[' + getSeverityColor(severity) + 'm' +
|
'\u001b['+getSeverityColor(severity)+'m' +
|
||||||
dateFormat(new Date(), 'yyyy-mm-dd HH:MM:ss') +
|
dateFormat(new Date(), 'yyyy-mm-dd HH:MM:ss') +
|
||||||
" [" + key + "]" + '\u001b[39m: ' + "\t" +
|
" ["+key+"]" + '\u001b[39m: ' + "\t" +
|
||||||
desc + text
|
desc +
|
||||||
);
|
text);
|
||||||
};
|
}
|
||||||
|
|
||||||
// public
|
// public
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
var Stratum = require('stratum-pool');
|
var Stratum = require('stratum-pool');
|
||||||
|
var Vardiff = require('stratum-pool/lib/varDiff.js');
|
||||||
|
var net = require('net');
|
||||||
|
|
||||||
var MposCompatibility = require('./mposCompatibility.js');
|
var MposCompatibility = require('./mposCompatibility.js');
|
||||||
var ShareProcessor = require('./shareProcessor.js');
|
var ShareProcessor = require('./shareProcessor.js');
|
||||||
@ -6,11 +8,15 @@ var ShareProcessor = require('./shareProcessor.js');
|
|||||||
module.exports = function(logger){
|
module.exports = function(logger){
|
||||||
|
|
||||||
|
|
||||||
var poolConfigs = JSON.parse(process.env.pools);
|
var poolConfigs = JSON.parse(process.env.pools);
|
||||||
var forkId = process.env.forkId;
|
var portalConfig = JSON.parse(process.env.portalConfig);
|
||||||
|
|
||||||
var pools = {};
|
var forkId = process.env.forkId;
|
||||||
|
|
||||||
|
var pools = {};
|
||||||
|
var varDiffsInstances = {}; // contains all the vardiffs for the profit switching pool
|
||||||
|
|
||||||
|
var proxyStuff = {}
|
||||||
//Handle messages from master process sent via IPC
|
//Handle messages from master process sent via IPC
|
||||||
process.on('message', function(message) {
|
process.on('message', function(message) {
|
||||||
switch(message.type){
|
switch(message.type){
|
||||||
@ -18,6 +24,23 @@ module.exports = function(logger){
|
|||||||
var pool = pools[message.coin.toLowerCase()]
|
var pool = pools[message.coin.toLowerCase()]
|
||||||
if (pool) pool.processBlockNotify(message.hash)
|
if (pool) pool.processBlockNotify(message.hash)
|
||||||
break;
|
break;
|
||||||
|
case 'switch':
|
||||||
|
var newCoinPool = pools[message.coin.toLowerCase()];
|
||||||
|
if (newCoinPool) {
|
||||||
|
var oldPool = pools[proxyStuff.curActivePool];
|
||||||
|
oldPool.relinquishMiners(
|
||||||
|
function (miner, cback) {
|
||||||
|
// relinquish miners that are attached to one of the "Auto-switch" ports and leave the others there.
|
||||||
|
cback(typeof(portalConfig.proxy.ports[miner.client.socket.localPort]) !== 'undefined')
|
||||||
|
},
|
||||||
|
function (clients) {
|
||||||
|
newCoinPool.attachMiners(clients);
|
||||||
|
proxyStuff.curActivePool = message.coin.toLowerCase();
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -131,4 +154,36 @@ module.exports = function(logger){
|
|||||||
pool.start();
|
pool.start();
|
||||||
pools[poolOptions.coin.name.toLowerCase()] = pool;
|
pools[poolOptions.coin.name.toLowerCase()] = pool;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
if (typeof(portalConfig.proxy) !== 'undefined' && portalConfig.proxy.enabled === true) {
|
||||||
|
proxyStuff.curActivePool = Object.keys(pools)[0];
|
||||||
|
proxyStuff.proxys = {};
|
||||||
|
proxyStuff.varDiffs = {};
|
||||||
|
Object.keys(portalConfig.proxy.ports).forEach(function(port) {
|
||||||
|
proxyStuff.varDiffs[port] = new Vardiff(port, portalConfig.proxy.ports[port].varDiff);
|
||||||
|
});
|
||||||
|
Object.keys(pools).forEach(function (coinName) {
|
||||||
|
var p = pools[coinName];
|
||||||
|
Object.keys(proxyStuff.varDiffs).forEach(function(port) {
|
||||||
|
p.setVarDiff(port, proxyStuff.varDiffs[port]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.keys(portalConfig.proxy.ports).forEach(function (port) {
|
||||||
|
|
||||||
|
proxyStuff.proxys[port] = net
|
||||||
|
.createServer({allowHalfOpen: true}, function(socket) {
|
||||||
|
console.log(proxyStuff.curActivePool);
|
||||||
|
pools[proxyStuff.curActivePool].getStratumServer().handleNewClient(socket);
|
||||||
|
} )
|
||||||
|
.listen(parseInt(port), function(){
|
||||||
|
console.log("Proxy listening on "+port);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
};
|
};
|
||||||
36
libs/redisblocknotifyListener.js
Normal file
36
libs/redisblocknotifyListener.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
var events = require('events');
|
||||||
|
var redis = require('redis');
|
||||||
|
|
||||||
|
var listener = module.exports = function listener(options){
|
||||||
|
|
||||||
|
var _this = this;
|
||||||
|
var redisConnection;
|
||||||
|
|
||||||
|
var emitLog = function(text){
|
||||||
|
_this.emit('log', text);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
this.start = function(){
|
||||||
|
redisConnection = redis.createClient(options.redisPort, options.redisHost);
|
||||||
|
redisConnection.on("pmessage", function (pattern, channel, message) {
|
||||||
|
var coinname = channel.split(':')[1];
|
||||||
|
var blockhash = message;
|
||||||
|
//emitLog("Redis: Received block for "+coinname+" - hash: "+blockhash);
|
||||||
|
_this.emit('hash', {
|
||||||
|
"coin" : coinname,
|
||||||
|
"hash" : blockhash
|
||||||
|
});
|
||||||
|
});
|
||||||
|
redisConnection.on('connect', function (err, data) {
|
||||||
|
emitLog("Redis connected");
|
||||||
|
});
|
||||||
|
redisConnection.psubscribe(options.psubscribeKey);
|
||||||
|
emitLog("Connecting to redis!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
listener.prototype.__proto__ = events.EventEmitter.prototype;
|
||||||
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"disabled": false,
|
"disabled": true,
|
||||||
"coin": "litecoin.json",
|
"coin": "litecoin.json",
|
||||||
|
|
||||||
"shareProcessing": {
|
"shareProcessing": {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user