From fcc44b19425ef36be0ad5bc8138ae0ee7b4f0ad1 Mon Sep 17 00:00:00 2001 From: Andrea Date: Fri, 14 Mar 2014 19:02:55 +0000 Subject: [PATCH 1/3] First things for the miners switch --- .gitignore | 3 +- config.json | 44 +++++++++++++++- init.js | 56 +++++++++++++++----- libs/logutils.js | 2 +- libs/poolWorker.js | 61 ++++++++++++++++++++-- libs/redisblocknotifyListener.js | 36 +++++++++++++ pool_configs/litecoin_testnet_example.json | 2 +- 7 files changed, 183 insertions(+), 21 deletions(-) create mode 100644 libs/redisblocknotifyListener.js diff --git a/.gitignore b/.gitignore index d35bbf7..ccd8331 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules/ -.idea/ \ No newline at end of file +.idea/ +pool_configs/ \ No newline at end of file diff --git a/config.json b/config.json index 2a2fdfd..b76bc54 100644 --- a/config.json +++ b/config.json @@ -1,11 +1,51 @@ { "clustering": { "enabled": true, - "forks": "auto" + "forks": "1" }, "blockNotifyListener": { - "enabled": true, + "enabled": false, "port": 8117, "password": "test" + }, + "redisBlockNotifyListener": { + "redisPort": 6379, + "redisHost": "coindaemons.ultimatecoinpool.com", + "psubscribeKey": "newblocks:*" + }, + "proxy": { + "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 + } + } + } } } \ No newline at end of file diff --git a/init.js b/init.js index 75619e4..7be2976 100644 --- a/init.js +++ b/init.js @@ -3,16 +3,17 @@ var os = require('os'); var cluster = require('cluster'); -var posix = require('posix'); -var PoolLogger = require('./libs/logutils.js'); -var BlocknotifyListener = require('./libs/blocknotifyListener.js'); -var WorkerListener = require('./libs/workerListener.js'); -var PoolWorker = require('./libs/poolWorker.js'); -var PaymentProcessor = require('./libs/paymentProcessor.js'); +var posix = require('posix'); +var PoolLogger = require('./libs/logutils.js'); +var BlocknotifyListener = require('./libs/blocknotifyListener.js'); +var RedisBlocknotifyListener = require('./libs/redisblocknotifyListener.js'); +var WorkerListener = require('./libs/workerListener.js'); +var PoolWorker = require('./libs/poolWorker.js'); +var PaymentProcessor = require('./libs/paymentProcessor.js'); JSON.minify = JSON.minify || require("node-json-minify"); - + var loggerInstance = new PoolLogger({ @@ -40,7 +41,7 @@ catch(e){ if (cluster.isWorker){ - + switch(process.env.workerType){ case 'pool': new PoolWorker(loggerInstance); @@ -51,6 +52,17 @@ if (cluster.isWorker){ } 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); + }); + }, 120000); } @@ -93,9 +105,10 @@ var spawnPoolWorkers = function(portalConfig, poolConfigs){ var createPoolWorker = function(forkId){ var worker = cluster.fork({ - workerType: 'pool', - forkId: forkId, - pools: serializedConfigs + workerType : 'pool', + forkId : forkId, + pools : serializedConfigs, + portalConfig : JSON.stringify(portalConfig), }); worker.on('exit', function(code, signal){ logError('poolWorker', 'system', 'Fork ' + forkId + ' died, spawning replacement worker...'); @@ -134,6 +147,21 @@ var startBlockListener = function(portalConfig){ 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 worker = cluster.fork({ @@ -147,7 +175,6 @@ var startPaymentProcessor = function(poolConfigs){ }; - (function init(){ var portalConfig = JSON.parse(JSON.minify(fs.readFileSync("config.json", {encoding: 'utf8'}))); @@ -159,6 +186,9 @@ var startPaymentProcessor = function(poolConfigs){ startBlockListener(portalConfig); + startRedisBlockListener(portalConfig); + startWorkerListener(poolConfigs); -})(); \ No newline at end of file + +})(); diff --git a/libs/logutils.js b/libs/logutils.js index 5ef890d..01054f5 100644 --- a/libs/logutils.js +++ b/libs/logutils.js @@ -63,7 +63,7 @@ var PoolLogger = function (configuration) { var desc = poolName ? '[' + poolName + '] ' : ''; console.log( '\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" + desc + text); diff --git a/libs/poolWorker.js b/libs/poolWorker.js index 3b00322..0b3c76f 100644 --- a/libs/poolWorker.js +++ b/libs/poolWorker.js @@ -1,4 +1,6 @@ var Stratum = require('stratum-pool'); +var Vardiff = require('stratum-pool/lib/varDiff.js'); +var net = require('net'); var MposCompatibility = require('./mposCompatibility.js'); var ShareProcessor = require('./shareProcessor.js'); @@ -6,11 +8,15 @@ var ShareProcessor = require('./shareProcessor.js'); module.exports = function(logger){ - var poolConfigs = JSON.parse(process.env.pools); - var forkId = process.env.forkId; + var poolConfigs = JSON.parse(process.env.pools); + 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 process.on('message', function(message) { switch(message.type){ @@ -18,6 +24,23 @@ module.exports = function(logger){ var pool = pools[message.coin.toLowerCase()] if (pool) pool.processBlockNotify(message.hash) 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(); 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); + }); + + }); + + + + } }; \ No newline at end of file diff --git a/libs/redisblocknotifyListener.js b/libs/redisblocknotifyListener.js new file mode 100644 index 0000000..05b9c7f --- /dev/null +++ b/libs/redisblocknotifyListener.js @@ -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; diff --git a/pool_configs/litecoin_testnet_example.json b/pool_configs/litecoin_testnet_example.json index 2e9430c..f1f4cb1 100644 --- a/pool_configs/litecoin_testnet_example.json +++ b/pool_configs/litecoin_testnet_example.json @@ -1,5 +1,5 @@ { - "disabled": false, + "disabled": true, "coin": "litecoin.json", "shareProcessing": { From 5b3c12508e73c4d1f9bc2d33a3a8a2566ca56686 Mon Sep 17 00:00:00 2001 From: Andrea Baccega Date: Fri, 14 Mar 2014 21:56:54 +0000 Subject: [PATCH 2/3] Merged stuff --- config.json | 40 +++++++++++++++++++++------------------- init.js | 31 +++++++------------------------ libs/logUtil.js | 9 --------- 3 files changed, 28 insertions(+), 52 deletions(-) diff --git a/config.json b/config.json index 297bc40..a88de0e 100644 --- a/config.json +++ b/config.json @@ -11,9 +11,10 @@ }, "redisBlockNotifyListener": { - "redisPort": 6379, - "redisHost": "coindaemons.ultimatecoinpool.com", - "psubscribeKey": "newblocks:*" + "enabled" : false, + "redisPort" : 6379, + "redisHost" : "hostname", + "psubscribeKey" : "newblocks:*" }, "proxy": { "enabled": true, @@ -21,36 +22,37 @@ "80": { "diff": 32, "varDiff": { - "minDiff": 8, - "maxDiff": 512, - "targetTime": 15, - "retargetTime": 90, - "variancePercent": 30 + "minDiff" : 8, + "maxDiff" : 512, + "targetTime" : 15, + "retargetTime" : 90, + "variancePercent" : 30 } }, "6000": { "diff": 32, "varDiff": { - "minDiff": 8, - "maxDiff": 512, - "targetTime": 15, - "retargetTime": 90, - "variancePercent": 30 + "minDiff" : 8, + "maxDiff" : 512, + "targetTime" : 15, + "retargetTime" : 90, + "variancePercent" : 30 } }, "8080": { "diff": 32, "varDiff": { - "minDiff": 8, - "maxDiff": 512, - "targetTime": 15, - "retargetTime": 90, - "variancePercent": 30 + "minDiff" : 8, + "maxDiff" : 512, + "targetTime" : 15, + "retargetTime" : 90, + "variancePercent" : 30 } } } + }, "website": { - "enabled": true, + "enabled": false, "port": 80, "liveStats": true } diff --git a/init.js b/init.js index cdd859f..7f430c7 100644 --- a/init.js +++ b/init.js @@ -3,33 +3,18 @@ var os = require('os'); var cluster = require('cluster'); -<<<<<<< HEAD var posix = require('posix'); -var PoolLogger = require('./libs/logutils.js'); +var PoolLogger = require('./libs/logUtil.js'); var BlocknotifyListener = require('./libs/blocknotifyListener.js'); var RedisBlocknotifyListener = require('./libs/redisblocknotifyListener.js'); var WorkerListener = require('./libs/workerListener.js'); var PoolWorker = require('./libs/poolWorker.js'); var PaymentProcessor = require('./libs/paymentProcessor.js'); - +var Website = require('./libs/website.js'); JSON.minify = JSON.minify || require("node-json-minify"); - -======= -var posix = require('posix'); -var PoolLogger = require('./libs/logUtil.js'); -var BlocknotifyListener = require('./libs/blocknotifyListener.js'); -var WorkerListener = require('./libs/workerListener.js'); -var PoolWorker = require('./libs/poolWorker.js'); -var PaymentProcessor = require('./libs/paymentProcessor.js'); -var Website = require('./libs/website.js'); - -JSON.minify = JSON.minify || require("node-json-minify"); - - var portalConfig = JSON.parse(JSON.minify(fs.readFileSync("config.json", {encoding: 'utf8'}))); ->>>>>>> 0db53a296f9b77ad6ff76b5f06c7156d5366a777 - + var loggerInstance = new PoolLogger({ logLevel: portalConfig.logLevel @@ -75,7 +60,7 @@ if (cluster.isWorker){ Object.keys(cluster.workers).forEach(function(id) { cluster.workers[id].send(ipcMessage); }); - }, 120000); + }, 20000); } @@ -193,6 +178,8 @@ var startPaymentProcessor = function(poolConfigs){ var startWebsite = function(portalConfig, poolConfigs){ + console.log(portalConfig.website); + if (!portalConfig.website.enabled) return; var worker = cluster.fork({ @@ -222,12 +209,8 @@ var startWebsite = function(portalConfig, poolConfigs){ startRedisBlockListener(portalConfig); startWorkerListener(poolConfigs); +; -<<<<<<< HEAD - -})(); -======= startWebsite(portalConfig, poolConfigs); })(); ->>>>>>> 0db53a296f9b77ad6ff76b5f06c7156d5366a777 diff --git a/libs/logUtil.js b/libs/logUtil.js index a6b5b32..92d1cbe 100644 --- a/libs/logUtil.js +++ b/libs/logUtil.js @@ -53,21 +53,12 @@ var PoolLogger = function (configuration) { var desc = poolName ? '[' + poolName + '] ' : ''; console.log( -<<<<<<< HEAD:libs/logutils.js '\u001b['+getSeverityColor(severity)+'m' + dateFormat(new Date(), 'yyyy-mm-dd HH:MM:ss') + " ["+key+"]" + '\u001b[39m: ' + "\t" + desc + text); } -======= - '\u001b[' + getSeverityColor(severity) + 'm' + - dateFormat(new Date(), 'yyyy-mm-dd HH:MM:ss') + - " [" + key + "]" + '\u001b[39m: ' + "\t" + - desc + text - ); - }; ->>>>>>> 0db53a296f9b77ad6ff76b5f06c7156d5366a777:libs/logUtil.js // public From ef95233a1fe5f4b40661fc07d1edf5aaced498a6 Mon Sep 17 00:00:00 2001 From: Andrea Baccega Date: Fri, 14 Mar 2014 21:58:21 +0000 Subject: [PATCH 3/3] Removed coin switch debug --- init.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/init.js b/init.js index 7f430c7..07f8ea9 100644 --- a/init.js +++ b/init.js @@ -50,7 +50,7 @@ if (cluster.isWorker){ } return; -} else { +} /* else { var coinNames = ['alphacoin','frankocoin','emerald','kittehcoin']; var curIndex = 0; setInterval(function () { @@ -61,7 +61,7 @@ if (cluster.isWorker){ cluster.workers[id].send(ipcMessage); }); }, 20000); -} +} */