diff --git a/README.md b/README.md index c7bd804..95146bc 100644 --- a/README.md +++ b/README.md @@ -170,7 +170,7 @@ Inside the `config_example.json` file, ensure the default configuration will wor Explanation for each field: ````javascript { - /* Specifies the level of log output verbosity. Anything more severy than the level specified + /* Specifies the level of log output verbosity. Anything more severe than the level specified will also be logged. */ "logLevel": "debug", //or "warning", "error" diff --git a/libs/shareProcessor.js b/libs/shareProcessor.js index 2632174..4495a00 100644 --- a/libs/shareProcessor.js +++ b/libs/shareProcessor.js @@ -14,6 +14,7 @@ value: a hash with.. */ + module.exports = function(logger, poolConfig){ var redisConfig = poolConfig.redis; @@ -38,6 +39,31 @@ module.exports = function(logger, poolConfig){ logger.error(logSystem, logComponent, logSubCat, 'Connection to redis database as been ended'); }); + connection.info(function(error, response){ + if (error){ + logger.error(logSystem, logComponent, logSubCat, 'Redis version check failed'); + return; + } + var parts = response.split('\r\n'); + var version; + var versionString; + for (var i = 0; i < parts.length; i++){ + if (parts[i].indexOf(':') !== -1){ + var valParts = parts[i].split(':'); + if (valParts[0] === 'redis_version'){ + versionString = valParts[1]; + version = parseFloat(versionString); + break; + } + } + } + if (!version){ + logger.error(logSystem, logComponent, logSubCat, 'Could not detect redis version - but be super old or broken'); + } + else if (version < 2.6){ + logger.error(logSystem, logComponent, logSubCat, "You're using redis version " + versionString + " the minimum required version is 2.6. Follow the damn usage instructions..."); + } + }); this.handleShare = function(isValidShare, isValidBlock, shareData){ @@ -47,17 +73,16 @@ module.exports = function(logger, poolConfig){ if (isValidShare){ redisCommands.push(['hincrbyfloat', coin + ':shares:roundCurrent', shareData.worker, shareData.difficulty]); redisCommands.push(['hincrby', coin + ':stats', 'validShares', 1]); - - /* Stores share diff, worker, and unique value with a score that is the timestamp. Unique value ensures it - doesn't overwrite an existing entry, and timestamp as score lets us query shares from last X minutes to - generate hashrate for each worker and pool. */ - var dateNow = Date.now(); - var hashrateData = [shareData.difficulty, shareData.worker, dateNow]; - redisCommands.push(['zadd', coin + ':hashrate', dateNow / 1000 | 0, hashrateData.join(':')]); } else{ redisCommands.push(['hincrby', coin + ':stats', 'invalidShares', 1]); } + /* Stores share diff, worker, and unique value with a score that is the timestamp. Unique value ensures it + doesn't overwrite an existing entry, and timestamp as score lets us query shares from last X minutes to + generate hashrate for each worker and pool. */ + var dateNow = Date.now(); + var hashrateData = [ isValidShare ? shareData.difficulty : -shareData.difficulty, shareData.worker, dateNow]; + redisCommands.push(['zadd', coin + ':hashrate', dateNow / 1000 | 0, hashrateData.join(':')]); if (isValidBlock){ redisCommands.push(['rename', coin + ':shares:roundCurrent', coin + ':shares:round' + shareData.height]); diff --git a/libs/stats.js b/libs/stats.js index 977002e..e128190 100644 --- a/libs/stats.js +++ b/libs/stats.js @@ -182,12 +182,28 @@ module.exports = function(logger, portalConfig, poolConfigs){ 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; + if (workerShares > 0) { + coinStats.shares += workerShares; + if (worker in coinStats.workers) + coinStats.workers[worker].shares += workerShares; + else + coinStats.workers[worker] = { + shares: workerShares, + invalidshares: 0, + hashrateString: null + }; + } + else { + if (worker in coinStats.workers) + coinStats.workers[worker].invalidshares -= workerShares; // workerShares is negative number! + else + coinStats.workers[worker] = { + shares: 0, + invalidshares: -workerShares, + hashrateString: null + }; + } }); var shareMultiplier = Math.pow(2, 32) / algos[coinStats.algorithm].multiplier; @@ -208,6 +224,10 @@ module.exports = function(logger, portalConfig, poolConfigs){ portalStats.algos[algo].hashrate += coinStats.hashrate; portalStats.algos[algo].workers += Object.keys(coinStats.workers).length; + for (var worker in coinStats.workers) { + coinStats.workers[worker].hashrateString = _this.getReadableHashRateString(shareMultiplier * coinStats.workers[worker].shares / portalConfig.website.stats.hashrateWindow); + } + delete coinStats.hashrates; delete coinStats.shares; coinStats.hashrateString = _this.getReadableHashRateString(coinStats.hashrate); diff --git a/libs/website.js b/libs/website.js index 4156d1f..7922dac 100644 --- a/libs/website.js +++ b/libs/website.js @@ -38,6 +38,7 @@ module.exports = function(logger){ 'getting_started.html': 'getting_started', 'stats.html': 'stats', 'tbs.html': 'tbs', + 'workers.html': 'workers', 'api.html': 'api', 'admin.html': 'admin', 'mining_key.html': 'mining_key' @@ -240,7 +241,7 @@ module.exports = function(logger){ next(); }); - app.get('/key.html', function(reg, res, next){ + app.get('/key.html', function(req, res, next){ res.end(keyScriptProcessed); }); diff --git a/website/index.html b/website/index.html index 03544ac..ea5f476 100644 --- a/website/index.html +++ b/website/index.html @@ -51,6 +51,12 @@ Tab Stats +
  • + +   + Workers Stats + +
  •   diff --git a/website/pages/workers.html b/website/pages/workers.html new file mode 100644 index 0000000..31b0eb4 --- /dev/null +++ b/website/pages/workers.html @@ -0,0 +1,66 @@ + + + +
    + +{{ for(var pool in it.stats.pools) { }} + +
    +
    {{=it.stats.pools[pool].name}}
    +
    + + + + + + + + + + + {{ for(var worker in it.stats.pools[pool].workers) { }} + {{var workerstat = it.stats.pools[pool].workers[worker];}} + + + + + + + + {{ } }} +
    AddressSharesInvalid sharesEfficiencyHashrate
    {{=worker}}{{=Math.floor(workerstat.shares)}}{{=Math.floor(workerstat.invalidshares)}}{{? workerstat.shares > 0}} {{=Math.floor(10000 * workerstat.shares / (workerstat.shares + workerstat.invalidshares)) / 100}}% {{??}} 0% {{?}}{{=workerstat.hashrateString}}
    +
    +
    +{{ } }}