From a0a8c0cd75fe2b4b6ab0082757aab404b4a34af5 Mon Sep 17 00:00:00 2001 From: Jerry Brady Date: Sun, 6 Apr 2014 00:12:00 +0000 Subject: [PATCH 1/3] fix issue #40 --- stats.js | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 stats.js diff --git a/stats.js b/stats.js new file mode 100644 index 0000000..7f2e126 --- /dev/null +++ b/stats.js @@ -0,0 +1,180 @@ +var redis = require('redis'); +var async = require('async'); + +var os = require('os'); + +var algos = require('stratum-pool/lib/algoProperties.js'); + + +module.exports = function(logger, portalConfig, poolConfigs){ + + var _this = this; + + var logSystem = 'Stats'; + + var redisClients = []; + + var canDoStats = true; + + Object.keys(poolConfigs).forEach(function(coin){ + + if (!canDoStats) return; + + var poolConfig = poolConfigs[coin]; + + if (!poolConfig.shareProcessing || !poolConfig.shareProcessing.internal){ + logger.error(logSystem, coin, 'Cannot do stats without internal share processing setup'); + canDoStats = false; + return; + } + + var internalConfig = poolConfig.shareProcessing.internal; + var redisConfig = internalConfig.redis; + + for (var i = 0; i < redisClients.length; i++){ + var client = redisClients[i]; + if (client.client.port === redisConfig.port && client.client.host === redisConfig.host){ + client.coins.push(coin); + return; + } + } + redisClients.push({ + coins: [coin], + client: redis.createClient(redisConfig.port, redisConfig.host) + }); + }); + + + this.stats = {}; + this.statsString = ''; + + this.getGlobalStats = function(callback){ + + var allCoinStats = {}; + + async.each(redisClients, function(client, callback){ + var windowTime = (((Date.now() / 1000) - portalConfig.website.hashrateWindow) | 0).toString(); + var redisCommands = []; + + + var redisComamndTemplates = [ + ['zremrangebyscore', '_hashrate', '-inf', '(' + windowTime], + ['zrangebyscore', '_hashrate', windowTime, '+inf'], + ['hgetall', '_stats'], + ['scard', '_blocksPending'], + ['scard', '_blocksConfirmed'], + ['scard', '_blocksOrphaned'] + ]; + + var commandsPerCoin = redisComamndTemplates.length; + + + client.coins.map(function(coin){ + redisComamndTemplates.map(function(t){ + var clonedTemplates = t.slice(0); + clonedTemplates[1] = coin + clonedTemplates [1]; + redisCommands.push(clonedTemplates); + }); + }); + + + client.client.multi(redisCommands).exec(function(err, replies){ + if (err){ + console.log('error with getting hashrate stats ' + JSON.stringify(err)); + callback(err); + } + else{ + for(var i = 0; i < replies.length; i += commandsPerCoin){ + var coinName = client.coins[i / commandsPerCoin | 0]; + var coinStats = { + name: coinName, + symbol: poolConfigs[coinName].coin.symbol.toUpperCase(), + algorithm: poolConfigs[coinName].coin.algorithm, + hashrates: replies[i + 1], + poolStats: replies[i + 2] != null ? replies[i + 2] : { validShares: 0, validBlocks: 0, invalidShares: 0 }, + blocks: { + pending: replies[i + 3], + confirmed: replies[i + 4], + orphaned: replies[i + 5] + } + }; + allCoinStats[coinStats.name] = (coinStats); + } + callback(); + } + }); + }, function(err){ + if (err){ + console.log('error getting all stats' + JSON.stringify(err)); + callback(); + return; + } + + var portalStats = { + global:{ + workers: 0, + hashrate: 0 + }, + algos: {}, + pools: allCoinStats + }; + + Object.keys(allCoinStats).forEach(function(coin){ + var coinStats = allCoinStats[coin]; + coinStats.workers = {}; + coinStats.shares = 0; + coinStats.hashrates.forEach(function(ins){ + var parts = ins.split(':'); + var workerShares = parseFloat(parts[0]); + coinStats.shares += workerShares; + var worker = parts[1]; + if (worker in coinStats.workers) + coinStats.workers[worker] += workerShares + else + coinStats.workers[worker] = workerShares + }); + var shareMultiplier = algos[coinStats.algorithm].multiplier || 0; + var hashratePre = shareMultiplier * coinStats.shares / portalConfig.website.hashrateWindow; + coinStats.hashrate = hashratePre | 0; + portalStats.global.workers += Object.keys(coinStats.workers).length; + + /* algorithm specific global stats */ + var algo = coinStats.algorithm; + if (!portalStats.algos.hasOwnProperty(algo)){ + portalStats.algos[algo] = { + workers: 0, + hashrate: 0, + hashrateString: null + }; + } + portalStats.algos[algo].hashrate += coinStats.hashrate; + portalStats.algos[algo].workers += Object.keys(coinStats.workers).length; + + delete coinStats.hashrates; + delete coinStats.shares; + coinStats.hashrateString = _this.getReadableHashRateString(coinStats.hashrate); + }); + + Object.keys(portalStats.algos).forEach(function(algo){ + var algoStats = portalStats.algos[algo]; + algoStats.hashrateString = _this.getReadableHashRateString(algoStats.hashrate); + }); + + _this.stats = portalStats; + _this.statsString = JSON.stringify(portalStats); + callback(); + }); + + }; + + this.getReadableHashRateString = function(hashrate){ + var i = -1; + var byteUnits = [ ' KH', ' MH', ' GH', ' TH', ' PH' ]; + do { + hashrate = hashrate / 1024; + i++; + } while (hashrate > 1024); + return hashrate.toFixed(2) + byteUnits[i]; + }; + +}; From a9737393fbdd6b0ee7a8a8a251c88f8e9f07f306 Mon Sep 17 00:00:00 2001 From: Jerry Brady Date: Sun, 6 Apr 2014 00:13:31 +0000 Subject: [PATCH 2/3] Revert "fix issue #40" This reverts commit a0a8c0cd75fe2b4b6ab0082757aab404b4a34af5. --- stats.js | 180 ------------------------------------------------------- 1 file changed, 180 deletions(-) delete mode 100644 stats.js diff --git a/stats.js b/stats.js deleted file mode 100644 index 7f2e126..0000000 --- a/stats.js +++ /dev/null @@ -1,180 +0,0 @@ -var redis = require('redis'); -var async = require('async'); - -var os = require('os'); - -var algos = require('stratum-pool/lib/algoProperties.js'); - - -module.exports = function(logger, portalConfig, poolConfigs){ - - var _this = this; - - var logSystem = 'Stats'; - - var redisClients = []; - - var canDoStats = true; - - Object.keys(poolConfigs).forEach(function(coin){ - - if (!canDoStats) return; - - var poolConfig = poolConfigs[coin]; - - if (!poolConfig.shareProcessing || !poolConfig.shareProcessing.internal){ - logger.error(logSystem, coin, 'Cannot do stats without internal share processing setup'); - canDoStats = false; - return; - } - - var internalConfig = poolConfig.shareProcessing.internal; - var redisConfig = internalConfig.redis; - - for (var i = 0; i < redisClients.length; i++){ - var client = redisClients[i]; - if (client.client.port === redisConfig.port && client.client.host === redisConfig.host){ - client.coins.push(coin); - return; - } - } - redisClients.push({ - coins: [coin], - client: redis.createClient(redisConfig.port, redisConfig.host) - }); - }); - - - this.stats = {}; - this.statsString = ''; - - this.getGlobalStats = function(callback){ - - var allCoinStats = {}; - - async.each(redisClients, function(client, callback){ - var windowTime = (((Date.now() / 1000) - portalConfig.website.hashrateWindow) | 0).toString(); - var redisCommands = []; - - - var redisComamndTemplates = [ - ['zremrangebyscore', '_hashrate', '-inf', '(' + windowTime], - ['zrangebyscore', '_hashrate', windowTime, '+inf'], - ['hgetall', '_stats'], - ['scard', '_blocksPending'], - ['scard', '_blocksConfirmed'], - ['scard', '_blocksOrphaned'] - ]; - - var commandsPerCoin = redisComamndTemplates.length; - - - client.coins.map(function(coin){ - redisComamndTemplates.map(function(t){ - var clonedTemplates = t.slice(0); - clonedTemplates[1] = coin + clonedTemplates [1]; - redisCommands.push(clonedTemplates); - }); - }); - - - client.client.multi(redisCommands).exec(function(err, replies){ - if (err){ - console.log('error with getting hashrate stats ' + JSON.stringify(err)); - callback(err); - } - else{ - for(var i = 0; i < replies.length; i += commandsPerCoin){ - var coinName = client.coins[i / commandsPerCoin | 0]; - var coinStats = { - name: coinName, - symbol: poolConfigs[coinName].coin.symbol.toUpperCase(), - algorithm: poolConfigs[coinName].coin.algorithm, - hashrates: replies[i + 1], - poolStats: replies[i + 2] != null ? replies[i + 2] : { validShares: 0, validBlocks: 0, invalidShares: 0 }, - blocks: { - pending: replies[i + 3], - confirmed: replies[i + 4], - orphaned: replies[i + 5] - } - }; - allCoinStats[coinStats.name] = (coinStats); - } - callback(); - } - }); - }, function(err){ - if (err){ - console.log('error getting all stats' + JSON.stringify(err)); - callback(); - return; - } - - var portalStats = { - global:{ - workers: 0, - hashrate: 0 - }, - algos: {}, - pools: allCoinStats - }; - - Object.keys(allCoinStats).forEach(function(coin){ - var coinStats = allCoinStats[coin]; - coinStats.workers = {}; - coinStats.shares = 0; - coinStats.hashrates.forEach(function(ins){ - var parts = ins.split(':'); - var workerShares = parseFloat(parts[0]); - coinStats.shares += workerShares; - var worker = parts[1]; - if (worker in coinStats.workers) - coinStats.workers[worker] += workerShares - else - coinStats.workers[worker] = workerShares - }); - var shareMultiplier = algos[coinStats.algorithm].multiplier || 0; - var hashratePre = shareMultiplier * coinStats.shares / portalConfig.website.hashrateWindow; - coinStats.hashrate = hashratePre | 0; - portalStats.global.workers += Object.keys(coinStats.workers).length; - - /* algorithm specific global stats */ - var algo = coinStats.algorithm; - if (!portalStats.algos.hasOwnProperty(algo)){ - portalStats.algos[algo] = { - workers: 0, - hashrate: 0, - hashrateString: null - }; - } - portalStats.algos[algo].hashrate += coinStats.hashrate; - portalStats.algos[algo].workers += Object.keys(coinStats.workers).length; - - delete coinStats.hashrates; - delete coinStats.shares; - coinStats.hashrateString = _this.getReadableHashRateString(coinStats.hashrate); - }); - - Object.keys(portalStats.algos).forEach(function(algo){ - var algoStats = portalStats.algos[algo]; - algoStats.hashrateString = _this.getReadableHashRateString(algoStats.hashrate); - }); - - _this.stats = portalStats; - _this.statsString = JSON.stringify(portalStats); - callback(); - }); - - }; - - this.getReadableHashRateString = function(hashrate){ - var i = -1; - var byteUnits = [ ' KH', ' MH', ' GH', ' TH', ' PH' ]; - do { - hashrate = hashrate / 1024; - i++; - } while (hashrate > 1024); - return hashrate.toFixed(2) + byteUnits[i]; - }; - -}; From 22697fed80f590a33149eb280d24dc8951ac177f Mon Sep 17 00:00:00 2001 From: Jerry Brady Date: Sun, 6 Apr 2014 00:14:07 +0000 Subject: [PATCH 3/3] fix issue #40 --- libs/stats.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libs/stats.js b/libs/stats.js index 05be656..7f2e126 100644 --- a/libs/stats.js +++ b/libs/stats.js @@ -91,7 +91,7 @@ module.exports = function(logger, portalConfig, poolConfigs){ symbol: poolConfigs[coinName].coin.symbol.toUpperCase(), algorithm: poolConfigs[coinName].coin.algorithm, hashrates: replies[i + 1], - poolStats: replies[i + 2], + poolStats: replies[i + 2] != null ? replies[i + 2] : { validShares: 0, validBlocks: 0, invalidShares: 0 }, blocks: { pending: replies[i + 3], confirmed: replies[i + 4], @@ -178,4 +178,3 @@ module.exports = function(logger, portalConfig, poolConfigs){ }; }; -