diff --git a/libs/paymentProcessor.js b/libs/paymentProcessor.js index 97e9691..5a8a9f9 100644 --- a/libs/paymentProcessor.js +++ b/libs/paymentProcessor.js @@ -603,7 +603,10 @@ function SetupForPool(logger, poolOptions, setupFinished) { let minerAddressPrefix = address.substring(0,2); let checkPrefix = (poolOptions.minerPrefix || false); - if (privateChain && poolZAddressPrefix == 'zs' && minerAddressLength == 78 && minerAddressPrefix == 'zs') { + if (typeof poolOptions.rewardsDisabled !== 'undefined' && poolOptions.rewardsDisabled.includes(address)) { + logger.warning(logSystem, logComponent, 'Rewards disabled for this adddress: ' + address + ', convert to address ' + (poolOptions.invalidAddress || poolOptions.address)); + return (poolOptions.invalidAddress || poolOptions.address); + } else if (privateChain && poolZAddressPrefix == 'zs' && minerAddressLength == 78 && minerAddressPrefix == 'zs') { //validate as sapling return address; } else if (privateChain && poolZAddressPrefix == 'zc' && minerAddressLength == 95 && minerAddressPrefix == 'zc') { diff --git a/libs/stats.js b/libs/stats.js index b0049cd..d647db2 100644 --- a/libs/stats.js +++ b/libs/stats.js @@ -25,31 +25,31 @@ function rediscreateClient(port, host, pass) { * @returns {Array} array of items in [[key,value],[key,value],...] format. */ function sortProperties(obj, sortedBy, isNumericSort, reverse) { - sortedBy = sortedBy || 1; // by default first key - isNumericSort = isNumericSort || false; // by default text sort - reverse = reverse || false; // by default no reverse - - var reversed = (reverse) ? -1 : 1; - - var sortable = []; - for (var key in obj) { - if (obj.hasOwnProperty(key)) { - sortable.push([key, obj[key]]); - } - } - if (isNumericSort) - sortable.sort(function (a, b) { - return reversed * (a[1][sortedBy] - b[1][sortedBy]); - }); - else - sortable.sort(function (a, b) { - var x = a[1][sortedBy].toLowerCase(), - y = b[1][sortedBy].toLowerCase(); - return x < y ? reversed * -1 : x > y ? reversed : 0; - }); - return sortable; // array in format [ [ key1, val1 ], [ key2, val2 ], ... ] + sortedBy = sortedBy || 1; // by default first key + isNumericSort = isNumericSort || false; // by default text sort + reverse = reverse || false; // by default no reverse + + var reversed = (reverse) ? -1 : 1; + + var sortable = []; + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + sortable.push([key, obj[key]]); + } + } + if (isNumericSort) + sortable.sort(function (a, b) { + return reversed * (a[1][sortedBy] - b[1][sortedBy]); + }); + else + sortable.sort(function (a, b) { + var x = a[1][sortedBy].toLowerCase(), + y = b[1][sortedBy].toLowerCase(); + return x < y ? reversed * -1 : x > y ? reversed : 0; + }); + return sortable; // array in format [ [ key1, val1 ], [ key2, val2 ], ... ] } - + module.exports = function(logger, portalConfig, poolConfigs){ var _this = this; @@ -101,19 +101,29 @@ module.exports = function(logger, portalConfig, poolConfigs){ async.each(_this.stats.pools, function(pool, pcb) { if (_this.stats.pools[pool.name].pending && _this.stats.pools[pool.name].pending.blocks) - for (var i=0; i<_this.stats.pools[pool.name].pending.blocks.length; i++) - allBlocks[pool.name+"-"+_this.stats.pools[pool.name].pending.blocks[i].split(':')[2]] = _this.stats.pools[pool.name].pending.blocks[i]; - + for (var i=0; i<_this.stats.pools[pool.name].pending.blocks.length; i++) { + let blockoutput = _this.stats.pools[pool.name].pending.blocks[i].split(':'); + blockoutput[3] = pool.name + '-miner'; + blockoutput = blockoutput.join(':'); + + allBlocks[pool.name+"-"+_this.stats.pools[pool.name].pending.blocks[i].split(':')[2]] = blockoutput; + } + if (_this.stats.pools[pool.name].confirmed && _this.stats.pools[pool.name].confirmed.blocks) - for (var i=0; i<_this.stats.pools[pool.name].confirmed.blocks.length; i++) - allBlocks[pool.name+"-"+_this.stats.pools[pool.name].confirmed.blocks[i].split(':')[2]] = _this.stats.pools[pool.name].confirmed.blocks[i]; - + for (var i=0; i<_this.stats.pools[pool.name].confirmed.blocks.length; i++) { + let blockoutput = _this.stats.pools[pool.name].confirmed.blocks[i].split(':'); + blockoutput[3] = pool.name + '-miner'; + blockoutput = blockoutput.join(':'); + + allBlocks[pool.name+"-"+_this.stats.pools[pool.name].confirmed.blocks[i].split(':')[2]] = blockoutput; + } + pcb(); }, function(err) { - cback(allBlocks); + cback(allBlocks); }); }; - + function gatherStatHistory(){ var retentionTime = (((Date.now() / 1000) - portalConfig.website.stats.historicalRetention) | 0).toString(); redisStats.zrangebyscore(['statHistory', retentionTime, '+inf'], function(err, replies){ @@ -133,34 +143,34 @@ module.exports = function(logger, portalConfig, poolConfigs){ }); } - function getWorkerStats(address) { - address = address.split(".")[0]; - if (address.length > 0 && address.startsWith('t')) { - for (var h in statHistory) { - for(var pool in statHistory[h].pools) { - - statHistory[h].pools[pool].workers.sort(sortWorkersByHashrate); - - for(var w in statHistory[h].pools[pool].workers){ - if (w.startsWith(address)) { - if (history[w] == null) { - history[w] = []; - } - if (workers[w] == null && stats.pools[pool].workers[w] != null) { - workers[w] = stats.pools[pool].workers[w]; - } - if (statHistory[h].pools[pool].workers[w].hashrate) { - history[w].push({time: statHistory[h].time, hashrate:statHistory[h].pools[pool].workers[w].hashrate}); - } - } - } - } - } - return JSON.stringify({"workers": workers, "history": history}); - } - return null; - } - + function getWorkerStats(address) { + address = address.split(".")[0]; + if (address.length > 0 && address.startsWith('t')) { + for (var h in statHistory) { + for(var pool in statHistory[h].pools) { + + statHistory[h].pools[pool].workers.sort(sortWorkersByHashrate); + + for(var w in statHistory[h].pools[pool].workers){ + if (w.startsWith(address)) { + if (history[w] == null) { + history[w] = []; + } + if (workers[w] == null && stats.pools[pool].workers[w] != null) { + workers[w] = stats.pools[pool].workers[w]; + } + if (statHistory[h].pools[pool].workers[w].hashrate) { + history[w].push({time: statHistory[h].time, hashrate:statHistory[h].pools[pool].workers[w].hashrate}); + } + } + } + } + } + return JSON.stringify({"workers": workers, "history": history}); + } + return null; + } + function addStatPoolHistory(stats){ var data = { time: stats.time, @@ -175,10 +185,10 @@ module.exports = function(logger, portalConfig, poolConfigs){ } _this.statPoolHistory.push(data); } - + var magnitude = 100000000; var coinPrecision = magnitude.toString().length - 1; - + function roundTo(n, digits) { if (digits === undefined) { digits = 0; @@ -192,7 +202,7 @@ module.exports = function(logger, portalConfig, poolConfigs){ var satoshisToCoins = function(satoshis){ return roundTo((satoshis / magnitude), coinPrecision); }; - + var coinsToSatoshies = function(coins){ return Math.round(coins * magnitude); }; @@ -200,7 +210,7 @@ module.exports = function(logger, portalConfig, poolConfigs){ function coinsRound(number) { return roundTo(number, coinPrecision); } - + function readableSeconds(t) { var seconds = Math.round(t); var minutes = Math.floor(seconds/60); @@ -219,7 +229,7 @@ module.exports = function(logger, portalConfig, poolConfigs){ _this.stats.coins = redisClients[0].coins; cback(); }; - + this.getPayout = function(address, cback){ async.waterfall([ function(callback){ @@ -231,38 +241,38 @@ module.exports = function(logger, portalConfig, poolConfigs){ cback(coinsRound(total).toFixed(8)); }); }; - - this.getTotalSharesByAddress = function(address, cback) { - var a = address.split(".")[0]; + + this.getTotalSharesByAddress = function(address, cback) { + var a = address.split(".")[0]; var client = redisClients[0].client, coins = redisClients[0].coins, shares = []; var pindex = parseInt(0); - var totalShares = parseFloat(0); - async.each(_this.stats.pools, function(pool, pcb) { + var totalShares = parseFloat(0); + async.each(_this.stats.pools, function(pool, pcb) { pindex++; - var coin = String(_this.stats.pools[pool.name].name); - client.hscan(coin + ':shares:roundCurrent', 0, "match", a+"*", "count", 1000, function(error, result) { + var coin = String(_this.stats.pools[pool.name].name); + client.hscan(coin + ':shares:roundCurrent', 0, "match", a+"*", "count", 1000, function(error, result) { if (error) { pcb(error); return; } - var workerName=""; - var shares = 0; - for (var i in result[1]) { - if (Math.abs(i % 2) != 1) { - workerName = String(result[1][i]); - } else { - shares += parseFloat(result[1][i]); - } - } + var workerName=""; + var shares = 0; + for (var i in result[1]) { + if (Math.abs(i % 2) != 1) { + workerName = String(result[1][i]); + } else { + shares += parseFloat(result[1][i]); + } + } if (shares>0) { totalShares = shares; } pcb(); - }); - }, function(err) { + }); + }, function(err) { if (err) { cback(0); return; @@ -271,37 +281,37 @@ module.exports = function(logger, portalConfig, poolConfigs){ cback(totalShares); return; } - }); - }; + }); + }; this.getBalanceByAddress = function(address, cback){ - var a = address.split(".")[0]; - + var a = address.split(".")[0]; + var client = redisClients[0].client, coins = redisClients[0].coins, balances = []; - - var totalHeld = parseFloat(0); - var totalPaid = parseFloat(0); + + var totalHeld = parseFloat(0); + var totalPaid = parseFloat(0); var totalImmature = parseFloat(0); - - async.each(_this.stats.pools, function(pool, pcb) { - var coin = String(_this.stats.pools[pool.name].name); - // get all immature balances from address - client.hscan(coin + ':immature', 0, "match", a+"*", "count", 10000, function(error, pends) { + + async.each(_this.stats.pools, function(pool, pcb) { + var coin = String(_this.stats.pools[pool.name].name); + // get all immature balances from address + client.hscan(coin + ':immature', 0, "match", a+"*", "count", 10000, function(error, pends) { // get all balances from address client.hscan(coin + ':balances', 0, "match", a+"*", "count", 10000, function(error, bals) { // get all payouts from address client.hscan(coin + ':payouts', 0, "match", a+"*", "count", 10000, function(error, pays) { - + var workerName = ""; var balAmount = 0; var paidAmount = 0; var pendingAmount = 0; - + var workers = {}; - + for (var i in pays[1]) { if (Math.abs(i % 2) != 1) { workerName = String(pays[1][i]); @@ -335,7 +345,7 @@ module.exports = function(logger, portalConfig, poolConfigs){ totalImmature += pendingAmount; } } - + for (var w in workers) { balances.push({ worker:String(w), @@ -344,23 +354,23 @@ module.exports = function(logger, portalConfig, poolConfigs){ immature:workers[w].immature }); } - + pcb(); }); }); }); - }, function(err) { - if (err) { - callback("There was an error getting balances"); - return; - } - - _this.stats.balances = balances; - _this.stats.address = address; - - cback({totalHeld:coinsRound(totalHeld), totalPaid:coinsRound(totalPaid), totalImmature:satoshisToCoins(totalImmature), balances}); - }); - }; + }, function(err) { + if (err) { + callback("There was an error getting balances"); + return; + } + + _this.stats.balances = balances; + _this.stats.address = address; + + cback({totalHeld:coinsRound(totalHeld), totalPaid:coinsRound(totalPaid), totalImmature:satoshisToCoins(totalImmature), balances}); + }); + }; this.getGlobalStats = function(callback){ @@ -379,9 +389,9 @@ module.exports = function(logger, portalConfig, poolConfigs){ ['scard', ':blocksPending'], ['scard', ':blocksConfirmed'], ['scard', ':blocksKicked'], - ['smembers', ':blocksPending'], - ['smembers', ':blocksConfirmed'], - ['hgetall', ':shares:roundCurrent'], + ['smembers', ':blocksPending'], + ['smembers', ':blocksConfirmed'], + ['hgetall', ':shares:roundCurrent'], ['hgetall', ':blocksPendingConfirms'], ['zrange', ':payments', -100, -1], ['hgetall', ':shares:timesCurrent'] @@ -411,6 +421,39 @@ module.exports = function(logger, portalConfig, poolConfigs){ marketStats = replies[i + 2] ? (JSON.parse(replies[i + 2].coinmarketcap)[0] || 0) : 0; } } + + //anonymize currentRoundShares + let currentRoundSharesIndex = 0; + for (var worker in replies[i + 8]) { + Object.defineProperty(replies[i+8], 'worker' + currentRoundSharesIndex, Object.getOwnPropertyDescriptor(replies[i+8], worker)); + delete replies[i+8][worker]; + currentRoundSharesIndex++; + } + + //anonymize currentRoundTimes + let currentRoundTimesIndex = 0; + for (var worker in replies[i + 11]) { + Object.defineProperty(replies[i+11], 'worker' + currentRoundTimesIndex, Object.getOwnPropertyDescriptor(replies[i+11], worker)); + delete replies[i+11][worker]; + currentRoundTimesIndex++; + } + + //anonymize confirmed blocks + for (var b=0; b < replies[i + 7].length; b++) { + let blockoutput = replies[i + 7][b].split(':'); + blockoutput[3] = coinName + '-miner'; + blockoutput = blockoutput.join(':'); + replies[i + 7][b] = blockoutput; + } + + //anonymize pending blocks + for (var b=0; b < replies[i + 6].length; b++) { + let blockoutput = replies[i + 6][b].split(':'); + blockoutput[3] = coinName + '-miner'; + blockoutput = blockoutput.join(':'); + replies[i + 6][b] = blockoutput; + } + var coinStats = { name: coinName, symbol: poolConfigs[coinName].coin.symbol.toUpperCase(), @@ -421,11 +464,11 @@ module.exports = function(logger, portalConfig, poolConfigs){ validBlocks: replies[i + 2] ? (replies[i + 2].validBlocks || 0) : 0, invalidShares: replies[i + 2] ? (replies[i + 2].invalidShares || 0) : 0, totalPaid: replies[i + 2] ? (replies[i + 2].totalPaid || 0) : 0, - networkBlocks: replies[i + 2] ? (replies[i + 2].networkBlocks || 0) : 0, - networkSols: replies[i + 2] ? (replies[i + 2].networkSols || 0) : 0, - networkSolsString: getReadableNetworkHashRateString(replies[i + 2] ? (replies[i + 2].networkSols || 0) : 0), - networkDiff: replies[i + 2] ? (replies[i + 2].networkDiff || 0) : 0, - networkConnections: replies[i + 2] ? (replies[i + 2].networkConnections || 0) : 0, + networkBlocks: replies[i + 2] ? (replies[i + 2].networkBlocks || 0) : 0, + networkSols: replies[i + 2] ? (replies[i + 2].networkSols || 0) : 0, + networkSolsString: getReadableNetworkHashRateString(replies[i + 2] ? (replies[i + 2].networkSols || 0) : 0), + networkDiff: replies[i + 2] ? (replies[i + 2].networkDiff || 0) : 0, + networkConnections: replies[i + 2] ? (replies[i + 2].networkConnections || 0) : 0, networkVersion: replies[i + 2] ? (replies[i + 2].networkSubVersion || 0) : 0, networkProtocolVersion: replies[i + 2] ? (replies[i + 2].networkProtocolVersion || 0) : 0 }, @@ -437,16 +480,16 @@ module.exports = function(logger, portalConfig, poolConfigs){ orphaned: replies[i + 5] }, /* show all pending blocks */ - pending: { - blocks: replies[i + 6].sort(sortBlocks), + pending: { + blocks: replies[i + 6].sort(sortBlocks), confirms: (replies[i + 9] || {}) - }, + }, /* show last 50 found blocks */ - confirmed: { - blocks: replies[i + 7].sort(sortBlocks).slice(0,50) - }, + confirmed: { + blocks: replies[i + 7].sort(sortBlocks).slice(0,50) + }, payments: [], - currentRoundShares: (replies[i + 8] || {}), + currentRoundShares: (replies[i + 8] || {}), currentRoundTimes: (replies[i + 11] || {}), maxRoundTime: 0, shareCount: 0, @@ -459,7 +502,31 @@ module.exports = function(logger, portalConfig, poolConfigs){ } catch(e) { jsonObj = null; } - if (jsonObj !== null) { + if (jsonObj !== null) { + //Anonymize paid amounts + let paymentIndex = 0; + for (var payment in jsonObj.amounts) { + Object.defineProperty(jsonObj.amounts, 'miner' + paymentIndex, Object.getOwnPropertyDescriptor(jsonObj.amounts, payment)); + delete jsonObj.amounts[payment]; + paymentIndex++; + } + + //Anonymize balances + let balanceIndex = 0; + for (var balance in jsonObj.balances) { + Object.defineProperty(jsonObj.balances, 'miner' + balanceIndex, Object.getOwnPropertyDescriptor(jsonObj.balances, balance)); + delete jsonObj.balances[balance]; + balanceIndex++; + } + + //Anonymize work + let workIndex = 0; + for (var work in jsonObj.work) { + Object.defineProperty(jsonObj.work, 'miner' + workIndex, Object.getOwnPropertyDescriptor(jsonObj.work, work)); + delete jsonObj.work[work]; + workIndex++; + } + coinStats.payments.push(jsonObj); } } @@ -491,103 +558,120 @@ module.exports = function(logger, portalConfig, poolConfigs){ Object.keys(allCoinStats).forEach(function(coin){ var coinStats = allCoinStats[coin]; coinStats.workers = {}; - coinStats.miners = {}; + coinStats.miners = {}; coinStats.shares = 0; coinStats.hashrates.forEach(function(ins){ var parts = ins.split(':'); var workerShares = parseFloat(parts[0]); - var miner = parts[1].split('.')[0]; + var miner = parts[1].split('.')[0]; var worker = parts[1]; - var diff = Math.round(parts[0] * 8192); + var diff = Math.round(parts[0] * 8192); if (workerShares > 0) { coinStats.shares += workerShares; - // build worker stats + // build worker stats if (worker in coinStats.workers) { coinStats.workers[worker].shares += workerShares; - coinStats.workers[worker].diff = diff; + coinStats.workers[worker].diff = diff; } else { coinStats.workers[worker] = { - name: worker, - diff: diff, + name: worker, + diff: diff, shares: workerShares, invalidshares: 0, - currRoundShares: 0, + currRoundShares: 0, currRoundTime: 0, - hashrate: null, + hashrate: null, hashrateString: null, - luckDays: null, - luckHours: null, - paid: 0, - balance: 0 + luckDays: null, + luckHours: null, + paid: 0, + balance: 0 }; - } - // build miner stats - if (miner in coinStats.miners) { - coinStats.miners[miner].shares += workerShares; - } else { - coinStats.miners[miner] = { - name: miner, - shares: workerShares, - invalidshares: 0, - currRoundShares: 0, + } + // build miner stats + if (miner in coinStats.miners) { + coinStats.miners[miner].shares += workerShares; + } else { + coinStats.miners[miner] = { + name: miner, + shares: workerShares, + invalidshares: 0, + currRoundShares: 0, currRoundTime: 0, - hashrate: null, - hashrateString: null, - luckDays: null, - luckHours: null - }; - } - } - else { - // build worker stats + hashrate: null, + hashrateString: null, + luckDays: null, + luckHours: null + }; + } + } else { + // build worker stats if (worker in coinStats.workers) { coinStats.workers[worker].invalidshares -= workerShares; // workerShares is negative number! - coinStats.workers[worker].diff = diff; + coinStats.workers[worker].diff = diff; } else { coinStats.workers[worker] = { - name: worker, - diff: diff, + name: worker, + diff: diff, shares: 0, - invalidshares: -workerShares, - currRoundShares: 0, + invalidshares: -workerShares, + currRoundShares: 0, currRoundTime: 0, - hashrate: null, + hashrate: null, hashrateString: null, - luckDays: null, - luckHours: null, - paid: 0, - balance: 0 + luckDays: null, + luckHours: null, + paid: 0, + balance: 0 }; - } - // build miner stats - if (miner in coinStats.miners) { - coinStats.miners[miner].invalidshares -= workerShares; // workerShares is negative number! - } else { - coinStats.miners[miner] = { - name: miner, - shares: 0, - invalidshares: -workerShares, - currRoundShares: 0, + } + // build miner stats + if (miner in coinStats.miners) { + coinStats.miners[miner].invalidshares -= workerShares; // workerShares is negative number! + } else { + coinStats.miners[miner] = { + name: miner, + shares: 0, + invalidshares: -workerShares, + currRoundShares: 0, currRoundTime: 0, - hashrate: null, - hashrateString: null, - luckDays: null, - luckHours: null - }; - } + hashrate: null, + hashrateString: null, + luckDays: null, + luckHours: null + }; + } } }); - + + //anonymize miners + let minerindex = 0; + for (var miner in coinStats.miners) { + Object.defineProperty(coinStats.miners, 'miner' + minerindex, Object.getOwnPropertyDescriptor(coinStats.miners, miner)); + coinStats.miners['miner' + minerindex].name = 'miner' + minerindex; + delete coinStats.miners[miner]; + minerindex++; + } + + //anonymize workers + let workerindex = 0; + for (var worker in coinStats.workers) { + Object.defineProperty(coinStats.workers, 'worker' + workerindex, Object.getOwnPropertyDescriptor(coinStats.workers, worker)); + coinStats.workers['worker' + workerindex].name = 'worker' + workerindex; + delete coinStats.workers[worker]; + workerindex++; + } + var shareMultiplier = Math.pow(2, 32) / algos[coinStats.algorithm].multiplier; coinStats.hashrate = shareMultiplier * coinStats.shares / portalConfig.website.stats.hashrateWindow; coinStats.hashrateString = _this.getReadableHashRateString(coinStats.hashrate); - + var _blocktime = 160; - var _networkHashRate = parseFloat(coinStats.poolStats.networkSols) * 1.2; - var _myHashRate = (coinStats.hashrate / 1000000) * 2; - coinStats.luckDays = ((_networkHashRate / _myHashRate * _blocktime) / (24 * 60 * 60)).toFixed(3); - coinStats.luckHours = ((_networkHashRate / _myHashRate * _blocktime) / (60 * 60)).toFixed(3); - coinStats.minerCount = Object.keys(coinStats.miners).length; + var _networkHashRate = parseFloat(coinStats.poolStats.networkSols) * 1.2; + var _myHashRate = (coinStats.hashrate / 1000000) * 2; + coinStats.luckDays = ((_networkHashRate / _myHashRate * _blocktime) / (24 * 60 * 60)).toFixed(3); + coinStats.luckHours = ((_networkHashRate / _myHashRate * _blocktime) / (60 * 60)).toFixed(3); + coinStats.minerCount = Object.keys(coinStats.miners).length; coinStats.workerCount = Object.keys(coinStats.workers).length; portalStats.global.workers += coinStats.workerCount; @@ -627,29 +711,29 @@ module.exports = function(logger, portalConfig, poolConfigs){ coinStats.shareCount = _shareTotal; coinStats.maxRoundTime = _maxTimeShare; coinStats.maxRoundTimeString = readableSeconds(_maxTimeShare); - + for (var worker in coinStats.workers) { - var _workerRate = shareMultiplier * coinStats.workers[worker].shares / portalConfig.website.stats.hashrateWindow; - var _wHashRate = (_workerRate / 1000000) * 2; - coinStats.workers[worker].luckDays = ((_networkHashRate / _wHashRate * _blocktime) / (24 * 60 * 60)).toFixed(3); - coinStats.workers[worker].luckHours = ((_networkHashRate / _wHashRate * _blocktime) / (60 * 60)).toFixed(3); - coinStats.workers[worker].hashrate = _workerRate; - coinStats.workers[worker].hashrateString = _this.getReadableHashRateString(_workerRate); - var miner = worker.split('.')[0]; - if (miner in coinStats.miners) { - coinStats.workers[worker].currRoundTime = coinStats.miners[miner].currRoundTime; - } + var _workerRate = shareMultiplier * coinStats.workers[worker].shares / portalConfig.website.stats.hashrateWindow; + var _wHashRate = (_workerRate / 1000000) * 2; + coinStats.workers[worker].luckDays = ((_networkHashRate / _wHashRate * _blocktime) / (24 * 60 * 60)).toFixed(3); + coinStats.workers[worker].luckHours = ((_networkHashRate / _wHashRate * _blocktime) / (60 * 60)).toFixed(3); + coinStats.workers[worker].hashrate = _workerRate; + coinStats.workers[worker].hashrateString = _this.getReadableHashRateString(_workerRate); + var miner = worker.split('.')[0]; + if (miner in coinStats.miners) { + coinStats.workers[worker].currRoundTime = coinStats.miners[miner].currRoundTime; + } } - for (var miner in coinStats.miners) { - var _workerRate = shareMultiplier * coinStats.miners[miner].shares / portalConfig.website.stats.hashrateWindow; - var _wHashRate = (_workerRate / 1000000) * 2; - coinStats.miners[miner].luckDays = ((_networkHashRate / _wHashRate * _blocktime) / (24 * 60 * 60)).toFixed(3); - coinStats.miners[miner].luckHours = ((_networkHashRate / _wHashRate * _blocktime) / (60 * 60)).toFixed(3); - coinStats.miners[miner].hashrate = _workerRate; - coinStats.miners[miner].hashrateString = _this.getReadableHashRateString(_workerRate); + for (var miner in coinStats.miners) { + var _workerRate = shareMultiplier * coinStats.miners[miner].shares / portalConfig.website.stats.hashrateWindow; + var _wHashRate = (_workerRate / 1000000) * 2; + coinStats.miners[miner].luckDays = ((_networkHashRate / _wHashRate * _blocktime) / (24 * 60 * 60)).toFixed(3); + coinStats.miners[miner].luckHours = ((_networkHashRate / _wHashRate * _blocktime) / (60 * 60)).toFixed(3); + coinStats.miners[miner].hashrate = _workerRate; + coinStats.miners[miner].hashrateString = _this.getReadableHashRateString(_workerRate); } - - // sort workers by name + + // sort workers by name coinStats.workers = sortWorkersByName(coinStats.workers); coinStats.miners = sortMinersByHashrate(coinStats.miners); @@ -666,7 +750,7 @@ module.exports = function(logger, portalConfig, poolConfigs){ portalStats.pools = sortPoolsByHashrate(portalStats.pools); _this.stats = portalStats; - + // save historical hashrate, not entire stats! var saveStats = JSON.parse(JSON.stringify(portalStats)); Object.keys(saveStats.pools).forEach(function(pool){ @@ -679,9 +763,9 @@ module.exports = function(logger, portalConfig, poolConfigs){ }); _this.statsString = JSON.stringify(saveStats); _this.statHistory.push(saveStats); - - addStatPoolHistory(portalStats); - + + addStatPoolHistory(portalStats); + var retentionTime = (((Date.now() / 1000) - portalConfig.website.stats.historicalRetention) | 0); for (var i = 0; i < _this.statHistory.length; i++){ @@ -701,42 +785,43 @@ module.exports = function(logger, portalConfig, poolConfigs){ if (err) logger.error(logSystem, 'Historics', 'Error adding stats to historics ' + JSON.stringify(err)); }); + callback(); }); }; function sortPoolsByName(objects) { - var newObject = {}; - var sortedArray = sortProperties(objects, 'name', false, false); - for (var i = 0; i < sortedArray.length; i++) { - var key = sortedArray[i][0]; - var value = sortedArray[i][1]; - newObject[key] = value; - } - return newObject; + var newObject = {}; + var sortedArray = sortProperties(objects, 'name', false, false); + for (var i = 0; i < sortedArray.length; i++) { + var key = sortedArray[i][0]; + var value = sortedArray[i][1]; + newObject[key] = value; + } + return newObject; } - + function sortPoolsByHashrate(objects) { - var newObject = {}; - var sortedArray = sortProperties(objects, 'hashrate', true, true); - for (var i = 0; i < sortedArray.length; i++) { - var key = sortedArray[i][0]; - var value = sortedArray[i][1]; - newObject[key] = value; - } - return newObject; + var newObject = {}; + var sortedArray = sortProperties(objects, 'hashrate', true, true); + for (var i = 0; i < sortedArray.length; i++) { + var key = sortedArray[i][0]; + var value = sortedArray[i][1]; + newObject[key] = value; + } + return newObject; } function sortPoolsByShares(objects) { - var newObject = {}; - var sortedArray = sortProperties(objects, 'shareSort', true, true); - for (var i = 0; i < sortedArray.length; i++) { - var key = sortedArray[i][0]; - var value = sortedArray[i][1]; - newObject[key] = value; - } - return newObject; + var newObject = {}; + var sortedArray = sortProperties(objects, 'shareSort', true, true); + for (var i = 0; i < sortedArray.length; i++) { + var key = sortedArray[i][0]; + var value = sortedArray[i][1]; + newObject[key] = value; + } + return newObject; } function sortBlocks(a, b) { @@ -746,56 +831,56 @@ module.exports = function(logger, portalConfig, poolConfigs){ if (as < bs) return 1; return 0; } - - function sortWorkersByName(objects) { - var newObject = {}; - var sortedArray = sortProperties(objects, 'name', false, false); - for (var i = 0; i < sortedArray.length; i++) { - var key = sortedArray[i][0]; - var value = sortedArray[i][1]; - newObject[key] = value; - } - return newObject; - } - - function sortMinersByHashrate(objects) { - var newObject = {}; - var sortedArray = sortProperties(objects, 'hashrate', true, true); - for (var i = 0; i < sortedArray.length; i++) { - var key = sortedArray[i][0]; - var value = sortedArray[i][1]; - newObject[key] = value; - } - return newObject; - } - - function sortWorkersByHashrate(a, b) { - if (a.hashrate === b.hashrate) { - return 0; - } - else { - return (a.hashrate < b.hashrate) ? -1 : 1; - } - } - + + function sortWorkersByName(objects) { + var newObject = {}; + var sortedArray = sortProperties(objects, 'name', false, false); + for (var i = 0; i < sortedArray.length; i++) { + var key = sortedArray[i][0]; + var value = sortedArray[i][1]; + newObject[key] = value; + } + return newObject; + } + + function sortMinersByHashrate(objects) { + var newObject = {}; + var sortedArray = sortProperties(objects, 'hashrate', true, true); + for (var i = 0; i < sortedArray.length; i++) { + var key = sortedArray[i][0]; + var value = sortedArray[i][1]; + newObject[key] = value; + } + return newObject; + } + + function sortWorkersByHashrate(a, b) { + if (a.hashrate === b.hashrate) { + return 0; + } + else { + return (a.hashrate < b.hashrate) ? -1 : 1; + } + } + this.getReadableHashRateString = function(hashrate){ - hashrate = (hashrate * 2); - if (hashrate < 1000000) { - return (Math.round(hashrate / 1000) / 1000 ).toFixed(2)+' Sol/s'; - } + hashrate = (hashrate * 2); + if (hashrate < 1000000) { + return (Math.round(hashrate / 1000) / 1000 ).toFixed(2)+' Sol/s'; + } var byteUnits = [ ' Sol/s', ' KSol/s', ' MSol/s', ' GSol/s', ' TSol/s', ' PSol/s' ]; var i = Math.floor((Math.log(hashrate/1000) / Math.log(1000)) - 1); hashrate = (hashrate/1000) / Math.pow(1000, i + 1); return hashrate.toFixed(2) + byteUnits[i]; }; - - function getReadableNetworkHashRateString(hashrate) { - hashrate = (hashrate * 1000000); - if (hashrate < 1000000) - return '0 Sol'; - var byteUnits = [ ' Sol/s', ' KSol/s', ' MSol/s', ' GSol/s', ' TSol/s', ' PSol/s' ]; - var i = Math.floor((Math.log(hashrate/1000) / Math.log(1000)) - 1); - hashrate = (hashrate/1000) / Math.pow(1000, i + 1); - return hashrate.toFixed(2) + byteUnits[i]; - } + + function getReadableNetworkHashRateString(hashrate) { + hashrate = (hashrate * 1000000); + if (hashrate < 1000000) + return '0 Sol'; + var byteUnits = [ ' Sol/s', ' KSol/s', ' MSol/s', ' GSol/s', ' TSol/s', ' PSol/s' ]; + var i = Math.floor((Math.log(hashrate/1000) / Math.log(1000)) - 1); + hashrate = (hashrate/1000) / Math.pow(1000, i + 1); + return hashrate.toFixed(2) + byteUnits[i]; + } }; diff --git a/website/default/static/miner_stats.js b/website/default/static/miner_stats.js index 36b53c3..3f23ffd 100644 --- a/website/default/static/miner_stats.js +++ b/website/default/static/miner_stats.js @@ -10,14 +10,14 @@ var totalPaid; var totalShares; function getReadableHashRateString(hashrate){ - hashrate = (hashrate * 2); - if (hashrate < 1000000) { - return (Math.round(hashrate / 1000) / 1000 ).toFixed(2)+' Sol/s'; - } - var byteUnits = [ ' Sol/s', ' KSol/s', ' MSol/s', ' GSol/s', ' TSol/s', ' PSol/s' ]; - var i = Math.floor((Math.log(hashrate/1000) / Math.log(1000)) - 1); - hashrate = (hashrate/1000) / Math.pow(1000, i + 1); - return hashrate.toFixed(2) + byteUnits[i]; + hashrate = (hashrate * 2); + if (hashrate < 1000000) { + return (Math.round(hashrate / 1000) / 1000 ).toFixed(2)+' Sol/s'; + } + var byteUnits = [ ' Sol/s', ' KSol/s', ' MSol/s', ' GSol/s', ' TSol/s', ' PSol/s' ]; + var i = Math.floor((Math.log(hashrate/1000) / Math.log(1000)) - 1); + hashrate = (hashrate/1000) / Math.pow(1000, i + 1); + return hashrate.toFixed(2) + byteUnits[i]; } function timeOfDayFormat(timestamp){ @@ -27,95 +27,95 @@ function timeOfDayFormat(timestamp){ } function getWorkerNameFromAddress(w) { - var worker = w; - if (w.split(".").length > 1) { - worker = w.split(".")[1]; - if (worker == null || worker.length < 1) { - worker = "noname"; - } - } else { - worker = "noname"; - } - return worker; + var worker = w; + if (w.split(".").length > 1) { + worker = w.split(".")[1]; + if (worker == null || worker.length < 1) { + worker = "noname"; + } + } else { + worker = "noname"; + } + return worker; } function buildChartData(){ var workers = {}; - for (var w in statData.history) { - var worker = getWorkerNameFromAddress(w); - var a = workers[worker] = (workers[worker] || { - hashrate: [] - }); - for (var wh in statData.history[w]) { - a.hashrate.push([statData.history[w][wh].time * 1000, statData.history[w][wh].hashrate]); - } - if (a.hashrate.length > workerHistoryMax) { - workerHistoryMax = a.hashrate.length; - } - } - - var i=0; + for (var w in statData.history) { + var worker = getWorkerNameFromAddress(w); + var a = workers[worker] = (workers[worker] || { + hashrate: [] + }); + for (var wh in statData.history[w]) { + a.hashrate.push([statData.history[w][wh].time * 1000, statData.history[w][wh].hashrate]); + } + if (a.hashrate.length > workerHistoryMax) { + workerHistoryMax = a.hashrate.length; + } + } + + var i=0; workerHashrateData = []; for (var worker in workers){ workerHashrateData.push({ key: worker, - disabled: (i > Math.min((_workerCount-1), 3)), + disabled: (i > Math.min((_workerCount-1), 3)), values: workers[worker].hashrate }); - i++; + i++; } } function updateChartData(){ var workers = {}; - for (var w in statData.history) { - var worker = getWorkerNameFromAddress(w); - // get a reference to lastest workerhistory - for (var wh in statData.history[w]) { } - //var wh = statData.history[w][statData.history[w].length - 1]; - var foundWorker = false; - for (var i = 0; i < workerHashrateData.length; i++) { - if (workerHashrateData[i].key === worker) { - foundWorker = true; - if (workerHashrateData[i].values.length >= workerHistoryMax) { - workerHashrateData[i].values.shift(); - } - workerHashrateData[i].values.push([statData.history[w][wh].time * 1000, statData.history[w][wh].hashrate]); - break; - } - } - if (!foundWorker) { - var hashrate = []; - hashrate.push([statData.history[w][wh].time * 1000, statData.history[w][wh].hashrate]); - workerHashrateData.push({ - key: worker, - values: hashrate - }); - rebuildWorkerDisplay(); - return true; - } - } - triggerChartUpdates(); - return false; + for (var w in statData.history) { + var worker = getWorkerNameFromAddress(w); + // get a reference to lastest workerhistory + for (var wh in statData.history[w]) { } + //var wh = statData.history[w][statData.history[w].length - 1]; + var foundWorker = false; + for (var i = 0; i < workerHashrateData.length; i++) { + if (workerHashrateData[i].key === worker) { + foundWorker = true; + if (workerHashrateData[i].values.length >= workerHistoryMax) { + workerHashrateData[i].values.shift(); + } + workerHashrateData[i].values.push([statData.history[w][wh].time * 1000, statData.history[w][wh].hashrate]); + break; + } + } + if (!foundWorker) { + var hashrate = []; + hashrate.push([statData.history[w][wh].time * 1000, statData.history[w][wh].hashrate]); + workerHashrateData.push({ + key: worker, + values: hashrate + }); + rebuildWorkerDisplay(); + return true; + } + } + triggerChartUpdates(); + return false; } function calculateAverageHashrate(worker) { - var count = 0; - var total = 1; - var avg = 0; - for (var i = 0; i < workerHashrateData.length; i++) { - count = 0; - for (var ii = 0; ii < workerHashrateData[i].values.length; ii++) { - if (worker == null || workerHashrateData[i].key === worker) { - count++; - avg += parseFloat(workerHashrateData[i].values[ii][1]); - } - } - if (count > total) - total = count; - } - avg = avg / total; - return avg; + var count = 0; + var total = 1; + var avg = 0; + for (var i = 0; i < workerHashrateData.length; i++) { + count = 0; + for (var ii = 0; ii < workerHashrateData[i].values.length; ii++) { + if (worker == null || workerHashrateData[i].key === worker) { + count++; + avg += parseFloat(workerHashrateData[i].values[ii][1]); + } + } + if (count > total) + total = count; + } + avg = avg / total; + return avg; } function triggerChartUpdates(){ @@ -141,67 +141,67 @@ function displayCharts() { } function updateStats() { - totalHash = statData.totalHash; - totalPaid = statData.paid; - totalBal = statData.balance; - totalImmature = statData.immature; - totalShares = statData.totalShares; - // do some calculations - var _blocktime = 250; - var _networkHashRate = parseFloat(statData.networkSols) * 1.2; - var _myHashRate = (totalHash / 1000000) * 2; - var luckDays = ((_networkHashRate / _myHashRate * _blocktime) / (24 * 60 * 60)).toFixed(3); - // update miner stats - $("#statsHashrate").text(getReadableHashRateString(totalHash)); - $("#statsHashrateAvg").text(getReadableHashRateString(calculateAverageHashrate(null))); - $("#statsLuckDays").text(luckDays); - $("#statsTotalImmature").text(totalImmature); - $("#statsTotalBal").text(totalBal); - $("#statsTotalPaid").text(totalPaid); - $("#statsTotalShares").text(totalShares.toFixed(2)); + totalHash = statData.totalHash; + totalPaid = statData.paid; + totalBal = statData.balance; + totalImmature = statData.immature; + totalShares = statData.totalShares; + // do some calculations + var _blocktime = 250; + var _networkHashRate = parseFloat(statData.networkSols) * 1.2; + var _myHashRate = (totalHash / 1000000) * 2; + var luckDays = ((_networkHashRate / _myHashRate * _blocktime) / (24 * 60 * 60)).toFixed(3); + // update miner stats + $("#statsHashrate").text(getReadableHashRateString(totalHash)); + $("#statsHashrateAvg").text(getReadableHashRateString(calculateAverageHashrate(null))); + $("#statsLuckDays").text(luckDays); + $("#statsTotalImmature").text(totalImmature); + $("#statsTotalBal").text(totalBal); + $("#statsTotalPaid").text(totalPaid); + $("#statsTotalShares").text(totalShares.toFixed(2)); } function updateWorkerStats() { - // update worker stats - var i=0; - for (var w in statData.workers) { i++; - var htmlSafeWorkerName = w.split('.').join('_').replace(/[^\w\s]/gi, ''); - var saneWorkerName = getWorkerNameFromAddress(w); - $("#statsHashrate"+htmlSafeWorkerName).text(getReadableHashRateString(statData.workers[w].hashrate)); - $("#statsHashrateAvg"+htmlSafeWorkerName).text(getReadableHashRateString(calculateAverageHashrate(saneWorkerName))); - $("#statsLuckDays"+htmlSafeWorkerName).text(statData.workers[w].luckDays); - $("#statsPaid"+htmlSafeWorkerName).text(statData.workers[w].paid); - $("#statsBalance"+htmlSafeWorkerName).text(statData.workers[w].balance); - $("#statsShares"+htmlSafeWorkerName).text(Math.round(statData.workers[w].currRoundShares * 100) / 100); - $("#statsDiff"+htmlSafeWorkerName).text(statData.workers[w].diff); - } + // update worker stats + var i=0; + for (var w in statData.workers) { i++; + var htmlSafeWorkerName = w.split('.').join('_').replace(/[^\w\s]/gi, ''); + var saneWorkerName = getWorkerNameFromAddress(w); + $("#statsHashrate"+htmlSafeWorkerName).text(getReadableHashRateString(statData.workers[w].hashrate)); + $("#statsHashrateAvg"+htmlSafeWorkerName).text(getReadableHashRateString(calculateAverageHashrate(saneWorkerName))); + $("#statsLuckDays"+htmlSafeWorkerName).text(statData.workers[w].luckDays); + $("#statsPaid"+htmlSafeWorkerName).text(statData.workers[w].paid); + $("#statsBalance"+htmlSafeWorkerName).text(statData.workers[w].balance); + $("#statsShares"+htmlSafeWorkerName).text(Math.round(statData.workers[w].currRoundShares * 100) / 100); + $("#statsDiff"+htmlSafeWorkerName).text(statData.workers[w].diff); + } } function addWorkerToDisplay(name, htmlSafeName, workerObj) { - var htmlToAdd = ""; - htmlToAdd = '
'; - if (htmlSafeName.indexOf("_") >= 0) { - htmlToAdd+= '
'+htmlSafeName.substr(htmlSafeName.indexOf("_")+1,htmlSafeName.length)+'
'; - } else { - htmlToAdd+= '
noname
'; - } - htmlToAdd+='
'+getReadableHashRateString(workerObj.hashrate)+' (Now)
'; - htmlToAdd+='
'+getReadableHashRateString(calculateAverageHashrate(name))+' (Avg)
'; - htmlToAdd+='
Diff: '+workerObj.diff+'
'; - htmlToAdd+='
Shares: '+(Math.round(workerObj.currRoundShares * 100) / 100)+'
'; - htmlToAdd+='
Luck '+workerObj.luckDays+' Days
'; - htmlToAdd+='
Bal: '+workerObj.balance+'
'; - htmlToAdd+='
Paid: '+workerObj.paid+'
'; - htmlToAdd+='
'; - $("#boxesWorkers").html($("#boxesWorkers").html()+htmlToAdd); + var htmlToAdd = ""; + htmlToAdd = '
'; + if (htmlSafeName.indexOf("_") >= 0) { + htmlToAdd+= '
'+htmlSafeName.substr(htmlSafeName.indexOf("_")+1,htmlSafeName.length)+'
'; + } else { + htmlToAdd+= '
noname
'; + } + htmlToAdd+='
'+getReadableHashRateString(workerObj.hashrate)+' (Now)
'; + htmlToAdd+='
'+getReadableHashRateString(calculateAverageHashrate(name))+' (Avg)
'; + htmlToAdd+='
Diff: '+workerObj.diff+'
'; + htmlToAdd+='
Shares: '+(Math.round(workerObj.currRoundShares * 100) / 100)+'
'; + htmlToAdd+='
Luck '+workerObj.luckDays+' Days
'; + htmlToAdd+='
Bal: '+workerObj.balance+'
'; + htmlToAdd+='
Paid: '+workerObj.paid+'
'; + htmlToAdd+='
'; + $("#boxesWorkers").html($("#boxesWorkers").html()+htmlToAdd); } function rebuildWorkerDisplay() { - $("#boxesWorkers").html(""); - var i=0; - for (var w in statData.workers) { i++; - var htmlSafeWorkerName = w.split('.').join('_').replace(/[^\w\s]/gi, ''); - var saneWorkerName = getWorkerNameFromAddress(w); - addWorkerToDisplay(saneWorkerName, htmlSafeWorkerName, statData.workers[w]); - } + $("#boxesWorkers").html(""); + var i=0; + for (var w in statData.workers) { i++; + var htmlSafeWorkerName = w.split('.').join('_').replace(/[^\w\s]/gi, ''); + var saneWorkerName = getWorkerNameFromAddress(w); + addWorkerToDisplay(saneWorkerName, htmlSafeWorkerName, statData.workers[w]); + } } // resize chart on window resize @@ -210,37 +210,37 @@ nv.utils.windowResize(triggerChartUpdates); // grab initial stats $.getJSON('/api/worker_stats?'+_miner, function(data){ statData = data; - for (var w in statData.workers) { _workerCount++; } - buildChartData(); - displayCharts(); - rebuildWorkerDisplay(); + for (var w in statData.workers) { _workerCount++; } + buildChartData(); + displayCharts(); + rebuildWorkerDisplay(); updateStats(); }); // live stat updates statsSource.addEventListener('message', function(e){ - // TODO, create miner_live_stats... - // miner_live_stats will return the same josn except without the worker history - // FOR NOW, use this to grab updated stats - $.getJSON('/api/worker_stats?'+_miner, function(data){ - statData = data; - // check for missing workers - var wc = 0; - var rebuilt = false; - // update worker stats - for (var w in statData.workers) { wc++; } - // TODO, this isn't 100% fool proof! - if (_workerCount != wc) { - if (_workerCount > wc) { - rebuildWorkerDisplay(); - rebuilt = true; - } - _workerCount = wc; - } - rebuilt = (rebuilt || updateChartData()); - updateStats(); - if (!rebuilt) { - updateWorkerStats(); - } - }); + // TODO, create miner_live_stats... + // miner_live_stats will return the same josn except without the worker history + // FOR NOW, use this to grab updated stats + $.getJSON('/api/worker_stats?'+_miner, function(data){ + statData = data; + // check for missing workers + var wc = 0; + var rebuilt = false; + // update worker stats + for (var w in statData.workers) { wc++; } + // TODO, this isn't 100% fool proof! + if (_workerCount != wc) { + if (_workerCount > wc) { + rebuildWorkerDisplay(); + rebuilt = true; + } + _workerCount = wc; + } + rebuilt = (rebuilt || updateChartData()); + updateStats(); + if (!rebuilt) { + updateWorkerStats(); + } + }); }); diff --git a/website/piratepool.io/static/payments.js b/website/piratepool.io/static/payments.js index 0cad5b2..f9f275a 100644 --- a/website/piratepool.io/static/payments.js +++ b/website/piratepool.io/static/payments.js @@ -49,12 +49,11 @@ $(function() { console.log('Added new payment!'); } } else { - //Update existing (txid) for private chains + //Update existing (txid) for private chains if (typeof paymentstat.txid !== 'undefined' && (String(stats.pools[pool].name).startsWith("pirate") || String(stats.pools[pool].name).startsWith("arrr")) ) { - var explorer = 'https://explorer.pirate.black/tx/'; var paymentblock = document.querySelector('#payment' + pool + paymentstat.time + ' .paymentblocks a'); - paymentblock.setAttribute('href', explorer + paymentstat.txid); + paymentblock.setAttribute('href', explorerURL + 'tx/' + paymentstat.txid); paymentblock.setAttribute('target', '_blank'); paymentblock.setAttribute('rel', 'noopener noreferrer'); } @@ -81,4 +80,4 @@ $(function() { } } }); -}); \ No newline at end of file +}); diff --git a/website/piratepool.io/static/stats.js b/website/piratepool.io/static/stats.js index e64c284..95f6d21 100644 --- a/website/piratepool.io/static/stats.js +++ b/website/piratepool.io/static/stats.js @@ -58,7 +58,7 @@ $(function() { insertPendingBlock.setAttribute('title', 'Waiting for payment processor to review'); insertPendingBlock.style.opacity = 0; insertPendingBlock.style.transition = 'opacity 1s ease-in'; - insertPendingBlock.innerHTML = '
Block: ' + checkblock[2] + '' + readableDate(checkblock[4]) + 'Pending
Mined By: ' + middleEllipsis(checkblock[3]) + '
'; + insertPendingBlock.innerHTML = '
Block: ' + checkblock[2] + '' + readableDate(checkblock[4]) + 'Pending
'; if (parseInt(checkblock[2]) > prevHeight) { poolFoundList.insertBefore(insertPendingBlock, poolFoundList.firstChild); @@ -85,7 +85,7 @@ $(function() { insertPendingBlock.id = 'blocksFoundPaid' + checkblock[0]; insertPendingBlock.setAttribute('class', 'blocksFoundPaid'); insertPendingBlock.setAttribute('title', 'Payment sent, please check payments page'); - insertPendingBlock.innerHTML = '
Block: ' + checkblock[2] + '' + readableDate(checkblock[4]) + 'Pending
Mined By: ' + middleEllipsis(checkblock[3]) + '
'; + insertPendingBlock.innerHTML = '
Block: ' + checkblock[2] + '' + readableDate(checkblock[4]) + 'Pending
'; poolFoundList.insertBefore(insertPendingBlock, document.querySelectorAll('.blocksFoundList .blocksFoundPaid')[0]); } @@ -146,4 +146,4 @@ function displayCharts(){ function triggerChartUpdates(){ poolHashrateChart.update(); -} \ No newline at end of file +} diff --git a/website/piratepool.io/static/style.css b/website/piratepool.io/static/style.css index a208032..ccb268a 100644 --- a/website/piratepool.io/static/style.css +++ b/website/piratepool.io/static/style.css @@ -13,7 +13,7 @@ } html, body, button, input, select, textarea, -.pure-g [class *= "pure-u"] { +.pure-g [class *= "pure-u"] { font-family: 'Roboto', sans-serif; line-height: 1.4em; } @@ -99,8 +99,8 @@ footer a { } .highlight { - color:var(--gold); - font-weight:900; + color:var(--gold); + font-weight:900; } .muted { @@ -117,11 +117,11 @@ br.responsiveonly { } .alertbar { - color:var(--gold); + color:var(--gold); font-weight:900; text-shadow: -3px -3px 0px #000; text-align:center; - padding:10px 0; + padding:10px 0; background-color:var(--dark-blue); } @@ -134,7 +134,7 @@ header .pure-menu { } header .home-menu, -header .home-menu .pure-menu-list, +header .home-menu .pure-menu-list, header .home-menu .pure-menu-list li { display: flex; align-items: center; @@ -151,7 +151,7 @@ header .home-menu a { transition:background-color 0.33s ease-out, color 0.33s ease-out; } -header .home-menu a:hover, +header .home-menu a:hover, header .home-menu .pure-menu-selected a { color: #FFF!important; background-color: var(--gold); @@ -162,7 +162,7 @@ header .home-menu li a i { margin-right:5px; } -.pure-menu.pure-menu-open, +.pure-menu.pure-menu-open, .pure-menu.pure-menu-horizontal li .pure-menu-children { border:none; } @@ -208,7 +208,7 @@ header .home-menu li a i { background-color: var(--dark-blue); color: white; max-width:640px; - margin:15px auto 10px auto; + margin:15px auto 10px auto; padding:5px 10px 10px; box-shadow: -1px -1px 0 #000; } @@ -265,7 +265,7 @@ header .home-menu li a i { } .blocksFoundList .countLabel { - float:right; + float:right; font-size:0.8em; line-height:1em; } @@ -298,7 +298,7 @@ header .home-menu li a i { } .blocksFoundHeader > div:nth-child(2) { - font-size:0.8em; + font-size:0.8em; text-align:right; } @@ -349,6 +349,11 @@ header .home-menu li a i { } .paymentblocks .fade { + display:none; +} + +.paymentblocksexpand .fade { + display:block; z-index: 10; background-image: linear-gradient(to bottom, rgba(20, 20, 20, 0), rgba(20, 20, 20, 1) 90%); width: 95%; @@ -370,11 +375,11 @@ header .home-menu li a i { transition: max-height 0.2s ease-out 0.33s; } -.paymentblocks a:hover { +.paymentblocksexpand a:hover { max-height: 1000px; } -.paymentblocks a:hover + .fade { +.paymentblocksexpand a:hover + .fade { opacity:0; } @@ -444,9 +449,9 @@ header .home-menu li a i { .nv-group.nv-series-0, .nv-series:first-of-type .nv-legend-symbol { - stroke-opacity: 1; - fill-opacity: 0.5; - fill: var(--gold)!important; + stroke-opacity: 1; + fill-opacity: 0.5; + fill: var(--gold)!important; stroke: var(--gold)!important; } @@ -468,32 +473,32 @@ header .home-menu li a i { font-size: 1em; line-height: 1em; } - + .home-menu li a i { margin-right:0; } - .pure-table { + .pure-table { border-top: 1px solid var(--grey); } - table, thead, tbody, th, td, tr { - display: block; + table, thead, tbody, th, td, tr { + display: block; } - thead tr { + thead tr { display:none; visiblity:hidden; } - tr { + tr { border-bottom: 1px solid var(--grey); } - td { + td { border: none; position: relative; - + } .pure-table td { @@ -508,11 +513,11 @@ header .home-menu li a i { br.responsiveonly { display:initial; } - + .responsivehide { display:none; } - + .boxWelcome h1, .boxWelcome h2 { text-align:center!important; @@ -525,7 +530,7 @@ header .home-menu li a i { .blocksFoundHeader > div { text-align:center!important; } - + .blocksFoundList > div { flex: 1; } @@ -534,17 +539,17 @@ header .home-menu li a i { display:inline-block; visibility:visible; } - + .pure-responsive-disable, .flex-responsive-disable { width: 100%; } - + .paymentblocks a { display:inline; } - + .paymentblocks .fade { display:none; } -} \ No newline at end of file +} diff --git a/website/piratepool.io/static/workers.js b/website/piratepool.io/static/workers.js index 4ec41aa..7cecee4 100644 --- a/website/piratepool.io/static/workers.js +++ b/website/piratepool.io/static/workers.js @@ -12,32 +12,34 @@ $(function() { for (var f = 0; f < poolKeys.length; f++) { var pool = poolKeys[f]; var sharesTotal = 0; + var minerIndex = 0; for (var addr in stats.pools[pool].miners) { + minerIndex++; var workerstat = stats.pools[pool].miners[addr]; sharesTotal += parseFloat(workerstat.shares); - var existingRow = document.querySelector('#workers' + pool + ' #worker' + addr); + var existingRow = document.querySelector('#workers' + pool + ' #worker' + minerIndex); var minerEfficiency = ( workerstat.shares > 0 ) ? Math.floor(10000 * workerstat.shares / (workerstat.shares + workerstat.invalidshares)) / 100 : 0; - + if (existingRow == null) { //Add new var insertMinerTr = document.createElement('tr'); - insertMinerTr.id = 'worker' + addr; + insertMinerTr.id = 'worker' + minerIndex; insertMinerTr.setAttribute('data-hashrate', workerstat.hashrate); - insertMinerTr.innerHTML = ' Address: '+ middleEllipsis(addr, 20) + ''; + insertMinerTr.innerHTML = 'Miner #'+ minerIndex +''; insertMinerTr.innerHTML += ' Shares: ' + bigNumber(workerstat.shares) + ''; insertMinerTr.innerHTML += ' Efficiency: ' + minerEfficiency + '%'; insertMinerTr.innerHTML += ' Hashrate: ' + workerstat.hashrateString + ''; document.querySelector('#workers' + pool + ' .poolMinerTable tbody').appendChild(insertMinerTr); - console.log('Added new miner! [' + addr + ']'); + console.log('Added new miner! [' + minerIndex + ']'); } else { //Update existing - document.querySelector('#workers' + pool + ' #worker' + addr + ' td:nth-child(2) span:nth-child(2)').innerHTML = bigNumber(workerstat.shares); - document.querySelector('#workers' + pool + ' #worker' + addr + ' td:nth-child(3) span:nth-child(2)').innerHTML = minerEfficiency + '%'; - document.querySelector('#workers' + pool + ' #worker' + addr + ' td:nth-child(4) span:nth-child(2)').innerHTML = workerstat.hashrateString; - document.querySelector('#workers' + pool + ' #worker' + addr).setAttribute('data-hashrate', workerstat.hashrate); + document.querySelector('#workers' + pool + ' #worker' + minerIndex + ' td:nth-child(2) span:nth-child(2)').innerHTML = bigNumber(workerstat.shares); + document.querySelector('#workers' + pool + ' #worker' + minerIndex + ' td:nth-child(3) span:nth-child(2)').innerHTML = minerEfficiency + '%'; + document.querySelector('#workers' + pool + ' #worker' + minerIndex + ' td:nth-child(4) span:nth-child(2)').innerHTML = workerstat.hashrateString; + document.querySelector('#workers' + pool + ' #worker' + minerIndex).setAttribute('data-hashrate', workerstat.hashrate); } } @@ -76,4 +78,4 @@ function searchKeyPress(e) return false; } return true; -} \ No newline at end of file +}