Browse Source

Merge pull request #22 from webworker01/validateworker

Validateworker updates, code formatting, heapdump memory profiling
pull/1/head
Web Worker 5 years ago
committed by GitHub
parent
commit
6e234dedf7
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      libs/paymentProcessor.js
  2. 593
      libs/stats.js
  3. 322
      website/default/static/miner_stats.js
  4. 11
      website/piratepool.io/index.html
  5. 6
      website/piratepool.io/pages/getting_started.html
  6. 26
      website/piratepool.io/pages/home.html
  7. 6
      website/piratepool.io/pages/miner_stats.html
  8. 8
      website/piratepool.io/pages/payments.html
  9. 8
      website/piratepool.io/pages/stats.html
  10. 8
      website/piratepool.io/pages/workers.html
  11. 3
      website/piratepool.io/static/payments.js
  12. 4
      website/piratepool.io/static/stats.js
  13. 9
      website/piratepool.io/static/style.css
  14. 18
      website/piratepool.io/static/workers.js

5
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') {

593
libs/stats.js

@ -25,29 +25,29 @@ 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){
@ -101,12 +101,22 @@ 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) {
@ -133,33 +143,33 @@ 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 = {
@ -232,37 +242,37 @@ module.exports = function(logger, portalConfig, poolConfigs){
});
};
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,25 +281,25 @@ 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
@ -349,18 +359,18 @@ module.exports = function(logger, portalConfig, poolConfigs){
});
});
});
}, function(err) {
if (err) {
callback("There was an error getting balances");
return;
}
}, function(err) {
if (err) {
callback("There was an error getting balances");
return;
}
_this.stats.balances = balances;
_this.stats.address = address;
_this.stats.balances = balances;
_this.stats.address = address;
cback({totalHeld:coinsRound(totalHeld), totalPaid:coinsRound(totalPaid), totalImmature:satoshisToCoins(totalImmature), balances});
});
};
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,
@ -460,6 +503,30 @@ module.exports = function(logger, portalConfig, poolConfigs){
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;
@ -629,27 +713,27 @@ module.exports = function(logger, portalConfig, poolConfigs){
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);
@ -680,7 +764,7 @@ 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);
@ -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) {
@ -747,55 +832,55 @@ module.exports = function(logger, portalConfig, poolConfigs){
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];
}
};

322
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 = '<div class="boxStats" id="boxStatsLeft" style="float:left; margin: 9px; min-width: 260px;"><div class="boxStatsList">';
if (htmlSafeName.indexOf("_") >= 0) {
htmlToAdd+= '<div class="boxLowerHeader">'+htmlSafeName.substr(htmlSafeName.indexOf("_")+1,htmlSafeName.length)+'</div>';
} else {
htmlToAdd+= '<div class="boxLowerHeader">noname</div>';
}
htmlToAdd+='<div><i class="fa fa-tachometer"></i> <span id="statsHashrate'+htmlSafeName+'">'+getReadableHashRateString(workerObj.hashrate)+'</span> (Now)</div>';
htmlToAdd+='<div><i class="fa fa-tachometer"></i> <span id="statsHashrateAvg'+htmlSafeName+'">'+getReadableHashRateString(calculateAverageHashrate(name))+'</span> (Avg)</div>';
htmlToAdd+='<div><i class="fa fa-shield"></i> <small>Diff:</small> <span id="statsDiff'+htmlSafeName+'">'+workerObj.diff+'</span></div>';
htmlToAdd+='<div><i class="fa fa-cog"></i> <small>Shares:</small> <span id="statsShares'+htmlSafeName+'">'+(Math.round(workerObj.currRoundShares * 100) / 100)+'</span></div>';
htmlToAdd+='<div><i class="fa fa-gavel"></i> <small>Luck <span id="statsLuckDays'+htmlSafeName+'">'+workerObj.luckDays+'</span> Days</small></div>';
htmlToAdd+='<div><i class="fa fa-money"></i> <small>Bal: <span id="statsBalance'+htmlSafeName+'">'+workerObj.balance+'</span></small></div>';
htmlToAdd+='<div><i class="fa fa-money"></i> <small>Paid: <span id="statsPaid'+htmlSafeName+'">'+workerObj.paid+'</span></small></div>';
htmlToAdd+='</div></div></div>';
$("#boxesWorkers").html($("#boxesWorkers").html()+htmlToAdd);
var htmlToAdd = "";
htmlToAdd = '<div class="boxStats" id="boxStatsLeft" style="float:left; margin: 9px; min-width: 260px;"><div class="boxStatsList">';
if (htmlSafeName.indexOf("_") >= 0) {
htmlToAdd+= '<div class="boxLowerHeader">'+htmlSafeName.substr(htmlSafeName.indexOf("_")+1,htmlSafeName.length)+'</div>';
} else {
htmlToAdd+= '<div class="boxLowerHeader">noname</div>';
}
htmlToAdd+='<div><i class="fa fa-tachometer"></i> <span id="statsHashrate'+htmlSafeName+'">'+getReadableHashRateString(workerObj.hashrate)+'</span> (Now)</div>';
htmlToAdd+='<div><i class="fa fa-tachometer"></i> <span id="statsHashrateAvg'+htmlSafeName+'">'+getReadableHashRateString(calculateAverageHashrate(name))+'</span> (Avg)</div>';
htmlToAdd+='<div><i class="fa fa-shield"></i> <small>Diff:</small> <span id="statsDiff'+htmlSafeName+'">'+workerObj.diff+'</span></div>';
htmlToAdd+='<div><i class="fa fa-cog"></i> <small>Shares:</small> <span id="statsShares'+htmlSafeName+'">'+(Math.round(workerObj.currRoundShares * 100) / 100)+'</span></div>';
htmlToAdd+='<div><i class="fa fa-gavel"></i> <small>Luck <span id="statsLuckDays'+htmlSafeName+'">'+workerObj.luckDays+'</span> Days</small></div>';
htmlToAdd+='<div><i class="fa fa-money"></i> <small>Bal: <span id="statsBalance'+htmlSafeName+'">'+workerObj.balance+'</span></small></div>';
htmlToAdd+='<div><i class="fa fa-money"></i> <small>Paid: <span id="statsPaid'+htmlSafeName+'">'+workerObj.paid+'</span></small></div>';
htmlToAdd+='</div></div></div>';
$("#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();
}
});
});

11
website/piratepool.io/index.html

@ -7,7 +7,7 @@
<title>piratepool.io - mining pool for PirateChain (ARRR) - the most private and anonymous mineable cryptocurrency - Pirate</title>
<meta name="description" content="The first and largest mining pool for PirateChain (ARRR). Low fees with some proceeds donated to development and marketing efforts. The most private and anonymous cryptocurrency in existence is mineable here on the Equihash algorithm by CPU, GPU, ASIC, NiceHash. - Pirate">
<meta name="description" content="The first and largest mining pool for PirateChain (ARRR). Low fees with 66% of proceeds donated to development and marketing efforts. The most private and anonymous cryptocurrency in existence is mineable here on the Equihash algorithm by CPU, GPU, ASIC, NiceHash. - Pirate">
<meta name="keywords" content="PirateChain,Pirate,ARRR,mining,pool,equihash,komodo,dpow,privacy,private,freedom">
<meta name="robots" content="index, follow">
@ -15,14 +15,15 @@
<meta property="og:type" content="website">
<meta property="og:title" content="PiratePool.io - mining pool for PirateChain (ARRR) - the most private mineable cryptocurrency - Pirate">
<meta property="og:site_name" content="PiratePool.io - mining pool for PirateChain (ARRR)">
<meta property="og:description" content="The first and largest mining pool for PirateChain (ARRR). Low fees with some proceeds donated to development and marketing efforts. The most private and anonymous cryptocurrency in existence is mineable here on the Equihash algorithm by CPU, GPU, ASIC, NiceHash. - Pirate">
<meta property="og:description" content="The first and largest mining pool for PirateChain (ARRR). Low fees with 66% of proceeds donated to development and marketing efforts. The most private and anonymous cryptocurrency in existence is mineable here on the Equihash algorithm by CPU, GPU, ASIC, NiceHash. - Pirate">
<meta property="og:url" content="https://piratepool.io">
<meta property="og:image" content="https://piratepool.io/static/pirate128.png">
<meta property="og:image:secure_url" content="https://piratepool.io/static/pirate128.png">
<meta property="og:image:width" content="128">
<meta property="og:image:height" content="128">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:description" content="The first and largest mining pool for PirateChain (ARRR). Low fees with some proceeds donated to development and marketing efforts. The most private and anonymous cryptocurrency in existence is mineable here on the Equihash algorithm by CPU, GPU, ASIC, NiceHash. - Pirate">
<meta name="twitter:description" content="The first and largest mining pool for PirateChain (ARRR). Low fees with 66% of proceeds donated to development and marketing efforts. The most private and anonymous cryptocurrency in existence is mineable here on the Equihash algorithm by CPU, GPU, ASIC, NiceHash. - Pirate">
<meta name="twitter:title" content="PiratePool.io - mining pool for PirateChain (ARRR) - the most private mineable cryptocurrency - Pirate">
<meta name="twitter:site" content="@webworker01">
<meta name="twitter:image" content="https://piratepool.io/static/pirate128.png">
@ -93,9 +94,9 @@
{{=it.page}}
</main>
<footer>
No warranties matey! If ye be 'aving any troubles, invoke yarrr right t' parlay at <a href="https://discord.gg/rZCXtCC" target="_blank" rel="noopener noreferrer" class="highlight">#pirate</a>
No warranties matey! If ye be 'aving any troubles, invoke yarrr right t' parlay at <!-- <a href="https://discord.gg/rZCXtCC" target="_blank" rel="noopener noreferrer" class="highlight">#pirate</a> --> <a href="https://discord.gg/ASMfX7B" target="_blank" rel="nofollow noreferrer noopener" class="highlight">#piratepool</a>
<br>
&lt;3 <a href="https://webworker.sh" alt="webworker01" target="_blank" rel="noopener noreferrer">🐸</a> &middot; Built with <a href="https://github.com/webworker01/knomp" target="_blank" rel="noopener noreferrer" class="highlight">knomp</a>
&lt;3 <a href="https://webworker.sh" alt="webworker01" target="_blank" rel="noopener noreferrer">🕷️</a> &middot; Built with <a href="https://github.com/webworker01/knomp" target="_blank" rel="noopener noreferrer" class="highlight">knomp</a>
</footer>
</body>
</html>

6
website/piratepool.io/pages/getting_started.html

@ -117,9 +117,9 @@
<h1 class="menuHeader" id="payments">Payments</h1>
<div class="gettingStartedContent">
<p>Payouts are currently scheduled once every 4 hours with a minimum payout of 42 ARRR.</p>
<p>Payouts are currently scheduled once every 4 hours with a minimum payout of 21 ARRR.</p>
<p>There is a limit of ~200 recipients that can be included in a single payout, so the pool payouts are monitored and the min payout adjusted accordingly to ensure a constant flow of payments.</p>
<p>If payments stop going out, do not worry! Funds are safu! Blocks can still be found and will be credited to your worker! Please check the <a href="https://discord.gg/rZCXtCC">#pools-and-operators channel in discord</a> to see if it's already being worked on.</p>
<p>If payments stop going out, do not worry! Funds are safu! Blocks can still be found and will be credited to your worker! Please check <!-- the <a href="https://discord.gg/rZCXtCC">#pools-and-operators channel in discord</a>--><a href="https://discord.gg/ASMfX7B" target="_blank" rel="nofollow noreferrer noopener" class="highlight">#piratepool in discord</a> to see if it's already being worked on.</p>
<p>Pending blocks have not yet been scanned by the payment processor. After being scanned, blocks will need to receive both <a href="https://komodoplatform.com/security-delayed-proof-of-work-dpow/" target="_blank" rel="noopener noreferrer">dPoW notarization</a> and 10 confirmations before being actually paid out.</p>
<p>On your worker stats page, <em class="highlight">pending</em> balance is the remaining estimated amount to be paid for blocks that
were scanned but not yet eligible for payout either because of
@ -131,7 +131,7 @@
<h1 class="menuHeader" id="createWallet">Generate Wallet and Address</h1>
<div class="gettingStartedContent">
<p><a href="https://pirate.black/wallets/" target="_blank" rel="noopener noreferrer">The Agama GUI Wallet for PIRATE</a> is available. For Agama support please visit <a href="https://discord.gg/qReShun">#newpirates on Discord</a></p>
<p><a href="https://medium.com/piratechain/pirateocean-wallet-guide-1cb80f70364c" target="_blank" rel="noopener noreferrer">The PirateOceanQT for PIRATE</a> is available. For wallet support please visit <a href="https://discord.gg/qReShun">#newpirates on Discord</a></p>
<h4>CLI Wallet:</h4>
<ol>

26
website/piratepool.io/pages/home.html

@ -2,8 +2,11 @@
<div>
<div class="alertbar">
<!-- Stop mining to exchange addresses&#8230; -->
300K+ ARRR donated to Onboarding/Dev and Marketing funds, made possible via KMD notary node income.<br>
Thank you for all who voted me into KMD notary node for 2019 in SH! ❤ 🐸</div>
<!-- 300K+ ARRR donated to Onboarding/Dev and Marketing funds, made possible via KMD notary node income.<br>
Thank you for all who voted me into KMD notary node for 2019 in SH! ❤ 🐸-->
<!-- New piratepool.io discord support and discussion channel created! <a href="https://discord.gg/ASMfX7B" target="_blank" rel="nofollow noreferrer noopener" class="highlight">join #piratepool</a> 🐸 -->
Payout strategy changed to PPLNT with 1 hour payout frequency! Join <a href="https://discord.gg/ASMfX7B" target="_blank" rel="nofollow noreferrer noopener" class="highlight">#piratepool</a> for support and discussion! 🐸
</div>
<div class="pure-g boxWelcome">
<div class="pure-u-1-3 pure-responsive-disable" style="display:flex; justify-content:center; align-items:center;">
<img src="/static/pirate128.png" style="width:128px; -webkit-filter: drop-shadow(-1px -1px 0 #000); filter: drop-shadow(-1px -1px 0 #000);" alt="piratepool.io - knomp" />
@ -11,8 +14,15 @@
<div class="pure-u-2-3 pure-responsive-disable">
<h1 style="font-size: 2em; text-align:left; font-weight:900; color:#BB9645; margin:5px 0 10px;" class="textshadow">piratepool.io</h1>
<h2 style="color:#FFF; font-weight:900; font-size:1.5em; margin:0 0 10px;">Mining Pool For PirateChain (ARRR)</h2>
<p>
Donating 66% of the pool fee to the PirateChain project!<br>
<em>33% to PIRATE dev and <a href="https://dexstats.info/onboarding.php" target="_blank" rel="noopener noreferrer">onboarding</a> <a href="https://explorer.pirate.black/address/RAzq6y7dsUKgfuzNjpzyGiuFzvrwuDheQw" target="_blank" rel="noopener noreferrer">fund</a>
<br />
33% to <a href="https://explorer.pirate.black/address/RD5PhyAUhapsvj5ps2cCHozsXZfQSvDdrZ" target="_blank" rel="noopener noreferrer">PIRATE Marketing</a>!</em>
</p>
<table style="width: 100%; margin: 15px auto; text-align: left;">
<tr><td style="width:50%;">Algorithm: </td><td>Equihash</td></tr>
<tr><td>Payout Strategy: </td><td>PPLNT</td></tr>
<tr><td>Payout Frequency: </td><td>{{=it.poolsConfigs['arrr'].paymentProcessing.paymentInterval/60/60}} Hours</td></tr>
<tr><td>Min Payout: </td><td>{{=it.poolsConfigs['arrr'].paymentProcessing.minimumPayment}} ARRR</td></tr>
<tr><td>Pool Fee: </td><td>1%</td></tr>
@ -36,19 +46,15 @@
</div>
<div style="max-width:640px; margin:10px auto; padding: 10px 10px 0;">
<p>
<em>1/3rd of the pool fee is donated to the PIRATE <a href="https://dexstats.info/onboarding.php" target="_blank" rel="noopener noreferrer">onboarding</a> <a href="https://explorer.pirate.black/address/RAzq6y7dsUKgfuzNjpzyGiuFzvrwuDheQw" target="_blank" rel="noopener noreferrer">fund</a> and <br />
1/3rd is donated to <a href="https://explorer.pirate.black/address/RD5PhyAUhapsvj5ps2cCHozsXZfQSvDdrZ" target="_blank" rel="noopener noreferrer">PIRATE Marketing</a>!</em>
</p>
<p>
<span style="font-weight:900;">Sprout stratum has been retired! <a href="https://piratepool.io/static/sproutfinal.txt" target="_blank" style=" text-decoration:underline; text-decoration-color:#BB9645">Final Sprout Payouts Report</a></span>
<a href="https://medium.com/piratechain/pirateocean-wallet-guide-1cb80f70364c" target="_blank" rel="noopener noreferrer">Download the latest PirateOcean wallet</a> and create a sapling address (<span class="highlight">starts with zs1</span>) and connect to the new stratum ports labeled as <strong><em>arrr</em></strong> on <a href="/getting_started" class="hot-swapper">Getting Started</a>.
</p>
<p>
<a href="https://github.com/KomodoPlatform/Agama/releases" target="_blank" rel="noopener noreferrer">Download the latest Agama wallet</a> and create a sapling address (<span class="highlight">starts with zs1</span>) and connect to the new stratum ports labeled as <strong><em>arrr</em></strong> on <a href="/getting_started" class="hot-swapper">Getting Started</a>.
{{ /* <span style="font-weight:900;">Sprout stratum has been retired! <a href="https://piratepool.io/static/sproutfinal.txt" target="_blank" style=" text-decoration:underline; text-decoration-color:#BB9645">Final Sprout Payouts Report</a></span> */ }}
</p>
<p>
<!-- <p>
You need to migrate sprout funds in your own zc wallet address by <span class="highlight">2019-02-01</span>. A quick guide on how to migrate can be <a href="https://github.com/PirateNetwork/docs/wiki/How-to-Migrate-Pirate-(ARRR)-from-sprout-address-to-sapling-address" target="_blank" rel="noopener noreferrer">found here</a>.
You could also try <a href="https://dexstats.info/pirateswap.php" target="_blank" rel="noopener noreferrer">this service to swap your coins</a>.
</p>
</p> -->
</div>
<div class="pure-g boxStats">

6
website/piratepool.io/pages/miner_stats.html

@ -1,5 +1,11 @@
{{ function middleEllipsis(x) { return x.length > 40 ? x.substring(0, 20) + '...' + x.substring(x.length-20, x.length): x; } }}
{{ function checkCompromised(m) { var compromised = ['zs10jprfefpt2ra88u2ml96nzh3dmlqqqfeha5l7g0x0s0d2awme0eqfyt4w7r7pee0na8tcz6ezzj', 'zs12urwtysy5rkqzy3xgaxeu9g3ezf4fr0wfq44xrnf48uq6ug8qfxp059lms06khekppquvzadxyf', 'zs16sk9n6lyc8ulzkrf5xc72cr07hkyjvvj2emeqjel7xmn90qaf9mj2m8vt34yw45l7syqxlmfe5v', 'zs16xlsu48grwgsr29c9ztcn8jl0s47rtyucv3dw0n2e6y00w0wtt3d4ukqk4sq4sycrdhtxxg7g3k', 'zs19whs7s29a2kn5d4s8mpdad0m4setz86sq64kpv0t2v263mrqvuducp6nlmlwvynltam9zm9mr0p', 'zs1au66ft2gyu8ylgkw70vy4we2ktzum52esl94875w44mu8cmw2dcwfc29kahgmvfwcagwy39ctee', 'zs1c83zjak7ealmn92hejmqmjc7h3ysvglc9n95z79dhajth4fmhmrnv5zxdkufzg6l489y6hwf694', 'zs1d9myt9rpvu6grsl3ntg9wv0dfuj4vhp4rr0m3f940tt6fpxy8adpx4uzs7hgtclqtqe4wq2sjr8', 'zs1df3t2wpdmsjmzd7pwet67grfgr900fg6hjy97hl9vv0tkf7w5eye2zur6xhhzhfxdceu740g04g', 'zs1g342mavfn70xf5pycn8xwu2zsc4vq3fe8zzg99dfkdsdr39rqszvnuzxdp238d3uaqg96mmrclq', 'zs1gp9egrus6zrjqmea23nae7pzpxdy9jt3w65j8netsrcctl3g9e0lrag4tgvctw3r7rhryj4f4ua', 'zs1jttxxfwurarqw3cmkf94ygfs8skh7xxjf83wuh4awq6zjcee9p804p6aurmxv5q02f2uxc3qm93', 'zs1kqaakh9tw8uj039e9hzkh0444rw533uh8r5http8mfjuakmglqyqrjvd2ertnk8j9jlvvnzne9r', 'zs1lpp9qdtj9tkqjfj64wkcprvp2kflpu8cxz8fgclx80uuu4ajsmslkxkx0fh49cpw2yyhxwk0yzg', 'zs1pd047rvjf6es3ypx6vnl7vgnngmt3mkegn4vjtymfy26rxzp97mpjw5y2gkmyljmk99qs2wa4c0', 'zs1qsr5r8fp9scdz4wt08h4uxnlmefl0dmukuzxzs3f8wx6tk6ged399c9taphhx0asagryjkqgya7', 'zs1r4kfr08dm5yx60yg535dzhnpg8m8s4dl8ap42exkwm6699prpw9zu8sgj6xjd5efmrnj6p4u0an', 'zs1sfj20kyt95sfvll20lraw5q22q2aagw2r3pcdgtlaw4epc9sdwymxzdsge8c84f707ytqpjlnx4', 'zs1stzrmj7rfwr8g0hcsgs7aln0vxwcss6h7qfvzkyf9f6vuupeq6eqhrx7kwa0kmm5dawf7f9j8hr', 'zs1u7sy6prj270ucxwcwh9sh7vr33lnlgs6a95nt4hzgwxwvtcesu240px90822mffc0epf2kjlrjq', 'zs1ued52v4gv83yrguw4gpp4j85mtz9euedmwlszqmldl99cgefz8tz4y60ttjgm4avpqegyhnesns', 'zs1uhnyckurr2x4e8ak6ffqes4ggth8n2vxlzyksd8ufv9zltdhggdnxcx4q2jfn8tuea3f7w4yevs', 'zs1v569xvf7klgw8ylgf0dvtd92dtmu669xcqv05qvxud78nt4zwwcjdz046ghq7lvs4r0d227sgrv', 'zs1xl7l6sn0r5nsa6cex87yp3z7j2mj9jgf32dng6qqp7ym66s8wkx9lykmd896uq62e5xlq2mkaqq', 'zs1yxspuhm7fd5ffrjlmxtsyuryaj983paurt794rg87ln98ekdsugexl7kfvjw97ejhv66ytd3454', 'zs1yyeyhf856aag8vxlq4mkhjs8qjrlxfzz67s4jgjazpedrqfj62tr4zkp3tsj6cgc3hggq4t5raf', 'zs1z4aqxzy2krpvu45mfqes74a20yjmeuxlj0s4x89zr932panatzsfh8wf90qulh5683cgg9q0u2v']; return compromised.indexOf(m) > -1; } }}
<div id="pageMiner">
{{ if (checkCompromised(it.stats.address)) { }}
<div class="alertbar">
Your wallet address was possibly comporomised! Please visit <a href="https://discord.gg/ASMfX7B" target="_blank" rel="noopener noreferrer">discord</a> for more details!
</div>
{{ } }}
<div id="topCharts">
<div class="chartWrapper">
<div class="chartLabel">

8
website/piratepool.io/pages/payments.html

@ -13,7 +13,11 @@ function timeTilNumbers(timestamp) {
}
}}
<div id="pagePayments">
<div class="alertbar">Payout frequency has been changed to 4 hours because miners have been mining to exchange addresses&#8230;</div>
<div class="alertbar">
<!-- Payout frequency has been changed to 4 hours because miners have been mining to exchange addresses&#8230;-->
<!-- Block Reward Halving occured at block <a href="https://explorer.pirate.black/block/00000000004332fdca73719414e6e595c5f9f909bf39df5ff68f56b008b29790" target="_blank" rel="nofollow noreferrer noopener">388,885</a>!! Join <a href="https://discord.gg/ASMfX7B" target="_blank" rel="nofollow noreferrer noopener" class="highlight">#piratepool</a> for support and discussion! 🐸 -->
Payout strategy changed to PPLNT with 1 hour payout frequency! Join <a href="https://discord.gg/ASMfX7B" target="_blank" rel="nofollow noreferrer noopener" class="highlight">#piratepool</a> for support and discussion! 🐸
</div>
{{ for(var pool in it.stats.pools) { }}
<div class="poolLabel">
{{=it.stats.pools[pool].name}} Payments<span class="responsivehide"> &#160;&#160;</span><br class="responsiveonly" />
@ -37,7 +41,7 @@ function timeTilNumbers(timestamp) {
<tbody>
{{ for(var p in it.stats.pools[pool].payments) { }}
<tr id="payment{{=pool}}{{=it.stats.pools[pool].payments[p].time}}">
<td class="paymentblocks" title="Blocks:{{=it.stats.pools[pool].payments[p].blocks.length}} {{=it.stats.pools[pool].payments[p].opid}}">
<td class="paymentblocks{{if (it.stats.pools[pool].payments[p].blocks.length > 9) { }} paymentblocksexpand{{ } }}" title="Blocks:{{=it.stats.pools[pool].payments[p].blocks.length}} {{=it.stats.pools[pool].payments[p].opid}}">
<span class="responsiveTableLabel"><i class="fas fa-link fa-fw"></i></span> <span>Blocks: [{{=it.stats.pools[pool].payments[p].blocks.length}}] </span>
{{if (String(it.stats.pools[pool].name) == "KMD") { }}
<a href="https://kmdexplorer.io/tx/{{=it.stats.pools[pool].payments[p].txid}}" target="_blank" rel="noopener noreferrer">{{=it.stats.pools[pool].payments[p].blocks}}</a>

8
website/piratepool.io/pages/stats.html

@ -3,6 +3,10 @@
{{ function bigNumber(x){ return (x > 1000000000000) ? (x / 1000000000000).toFixed(1) + 'T' : (x > 1000000000) ? (x / 1000000000).toFixed(1) + 'B' : (x > 1000000) ? (x / 1000000).toFixed(1) + 'M' : (x > 1000) ? (x / 1000).toFixed(1) + 'K' : x.toFixed(1); } }}
{{ function middleEllipsis(x) { return x.length > 40 ? x.substring(0, 15) + '...' + x.substring(x.length-15, x.length): x; } }}
<div id="pageStats">
<div class="alertbar">
<!-- New piratepool.io discord support and discussion channel created! <a href="https://discord.gg/ASMfX7B" target="_blank" rel="nofollow noreferrer noopener" class="highlight">join #piratepool</a> 🐸 -->
Payout strategy changed to PPLNT with 1 hour payout frequency! Join <a href="https://discord.gg/ASMfX7B" target="_blank" rel="nofollow noreferrer noopener" class="highlight">#piratepool</a> for support and discussion! 🐸
</div>
<div id="topCharts">
<div class="chartWrapper">
<h1 class="chartLabel">Pool Hashrate</h1>
@ -35,7 +39,7 @@
<li><i class="fas fa-link fa-fw" aria-hidden="true"></i> Block Height: <span id="statsNetworkBlocks{{=pool}}">{{=it.stats.pools[pool].poolStats.networkBlocks}}</span></li>
<li><i class="fas fa-tachometer-alt fa-fw"></i> Network Hash/s: <span id="statsNetworkSols{{=pool}}">{{=it.stats.pools[pool].poolStats.networkSolsString}}</span></li>
<li><i class="fas fa-unlock-alt fa-fw" aria-hidden="true"></i> Difficulty: <span id="statsNetworkDiff{{=pool}}">{{=bigNumber(it.stats.pools[pool].poolStats.networkDiff)}}</span></li>
<li><i class="fas fa-coins fa-fw"></i> Total Supply: <span id="statsNetworkCoins{{=pool}}">{{=(it.stats.pools[pool].poolStats.networkBlocks*256).toLocaleString('en')}}</span></li>
<li><i class="fas fa-coins fa-fw"></i> Total Supply: <span id="statsNetworkCoins{{=pool}}">{{=(99554304+(it.stats.pools[pool].poolStats.networkBlocks-388884)*128).toLocaleString('en')}}</span></li>
<li><i class="fas fa-users fa-fw"></i> Node Connections: <span id="statsNetworkConnections{{=pool}}">{{=it.stats.pools[pool].poolStats.networkConnections}}</span></li>
</ul>
</div>
@ -79,7 +83,6 @@
<span class="countLabel">Pending</span>
{{ } }}
</div>
<div><i class="fas fa-crown fa-fw"></i> <small>Mined By:</small> <a href="/workers/{{=block[3].split('.')[0]}}" class="minerAddress" title="{{=block[3]}}">{{=middleEllipsis(block[3])}}</a></div>
</div>
{{ } }}
@ -95,7 +98,6 @@
{{ } }}
<span class="countLabel">Paid</span>
</div>
<div><i class="fas fa-crown fa-fw"></i> <small>Mined By:</small> <a href="/workers/{{=block[3].split('.')[0]}}" class="minerAddress" title="{{=block[3]}}">{{=middleEllipsis(block[3])}}</a></div>
</div>
{{ } }}
</div>

8
website/piratepool.io/pages/workers.html

@ -24,17 +24,19 @@
<table class="pure-table poolMinerTable">
<thead>
<tr>
<th>Address</th>
<th>Miner</th>
<th>Shares</th>
<th>Efficiency</th>
<th>Hashrate</th>
</tr>
</thead>
<tbody>
{{ var minerindex = 0; }}
{{ for(var worker in it.stats.pools[pool].miners) { }}
{{ minerindex++; }}
{{var workerstat = it.stats.pools[pool].miners[worker];}}
<tr id="worker{{=worker}}" data-hashrate="{{=workerstat.hashrate}}">
<td><span class="responsiveTableLabel"><i class="far fa-address-card fa-fw"></i> Address: </span><a href="/workers/{{=worker.split('.')[0]}}" title="{{=worker}}">{{=middleEllipsis(worker)}}</a></td>
<tr id="worker{{=minerindex}}" data-hashrate="{{=workerstat.hashrate}}">
<td><span class="responsiveTableLabel"><i class="far fa-address-card fa-fw"></i></span>Miner #{{=minerindex}}</td>
<td><span class="responsiveTableLabel"><i class="fas fa-cog fa-fw"></i> Shares: </span><span>{{=bigNumber(workerstat.currRoundShares)}}</span></td>
<td><span class="responsiveTableLabel"><i class="fas fa-bullseye fa-fw"></i> Efficiency: </span><span>{{? workerstat.shares > 0}} {{=Math.floor(10000 * workerstat.shares / (workerstat.shares + workerstat.invalidshares)) / 100}}% {{??}} 0% {{?}}</span></td>
<td><span class="responsiveTableLabel"><i class="fas fa-tachometer-alt fa-fw"></i> Hashrate: </span><span>{{=workerstat.hashrateString}}</span></td>

3
website/piratepool.io/static/payments.js

@ -51,10 +51,9 @@ $(function() {
} else {
//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');
}

4
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 = '<div><i class="fas fa-link fa-fw"></i> <small>Block:</small> <a href="' + explorerURL + 'block/' + checkblock[0] + '" target="_blank" rel="noopener noreferrer">' + checkblock[2] + '</a><span style="padding-left: 10px;"><small>' + readableDate(checkblock[4]) + '</small></span><span class="countLabel">Pending</span></div><div><i class="fas fa-crown fa-fw"></i> <small>Mined By:</small> <a href="/workers/' + checkblock[3].split('.')[0] + '" class="minerAddress" title="' + checkblock[3] + '">' + middleEllipsis(checkblock[3]) + '</a></div>';
insertPendingBlock.innerHTML = '<div><i class="fas fa-link fa-fw"></i> <small>Block:</small> <a href="' + explorerURL + 'block/' + checkblock[0] + '" target="_blank" rel="noopener noreferrer">' + checkblock[2] + '</a><span style="padding-left: 10px;"><small>' + readableDate(checkblock[4]) + '</small></span><span class="countLabel">Pending</span></div>';
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 = '<div><i class="fas fa-link fa-fw"></i> <small>Block:</small> <a href="' + explorerURL + 'block/' + checkblock[0] + '" target="_blank" rel="noopener noreferrer">' + checkblock[2] + '</a><span style="padding-left: 10px;"><small>' + readableDate(checkblock[4]) + '</small></span><span class="countLabel">Pending</span></div><div><i class="fas fa-crown fa-fw"></i> <small>Mined By:</small> <a href="/workers/' + checkblock[3].split('.')[0] + '" class="minerAddress" title="' + checkblock[3] + '">' + middleEllipsis(checkblock[3]) + '</a></div>';
insertPendingBlock.innerHTML = '<div><i class="fas fa-link fa-fw"></i> <small>Block:</small> <a href="' + explorerURL + 'block/' + checkblock[0] + '" target="_blank" rel="noopener noreferrer">' + checkblock[2] + '</a><span style="padding-left: 10px;"><small>' + readableDate(checkblock[4]) + '</small></span><span class="countLabel">Pending</span></div>';
poolFoundList.insertBefore(insertPendingBlock, document.querySelectorAll('.blocksFoundList .blocksFoundPaid')[0]);
}

9
website/piratepool.io/static/style.css

@ -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;
}

18
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 = '<td><span class="responsiveTableLabel"><i class="far fa-address-card fa-fw"></i> Address: </span><a href="/workers/' + addr + '" title="' + addr + '">'+ middleEllipsis(addr, 20) + '</a></td>';
insertMinerTr.innerHTML = '<td><span class="responsiveTableLabel"><i class="far fa-address-card fa-fw"></i></span>Miner #'+ minerIndex +'</td>';
insertMinerTr.innerHTML += '<td><span class="responsiveTableLabel"><i class="fas fa-cog fa-fw"></i> Shares: </span><span>' + bigNumber(workerstat.shares) + '</span></td>';
insertMinerTr.innerHTML += '<td><span class="responsiveTableLabel"><i class="fas fa-bullseye fa-fw"></i> Efficiency: </span><span> ' + minerEfficiency + '%</span></td>';
insertMinerTr.innerHTML += '<td><span class="responsiveTableLabel"><i class="fas fa-tachometer-alt fa-fw"></i> Hashrate: </span><span>' + workerstat.hashrateString + '</span></td>';
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);
}
}

Loading…
Cancel
Save