191 lines
5.8 KiB
JavaScript
191 lines
5.8 KiB
JavaScript
/**
|
|
* Cryptonote Node.JS Pool
|
|
* https://github.com/dvandal/cryptonote-nodejs-pool
|
|
*
|
|
* Utilities functions
|
|
**/
|
|
|
|
// Load required module
|
|
let crypto = require('crypto');
|
|
|
|
let dateFormat = require('dateformat');
|
|
exports.dateFormat = dateFormat;
|
|
|
|
let cnUtil = require('cryptoforknote-util');
|
|
exports.cnUtil = cnUtil;
|
|
|
|
/**
|
|
* Generate random instance id
|
|
**/
|
|
exports.instanceId = function(size=4) {
|
|
return crypto.randomBytes(size);
|
|
}
|
|
|
|
/**
|
|
* Validate miner address
|
|
**/
|
|
let addressBase58Prefix = parseInt(cnUtil.address_decode(Buffer.from(config.poolServer.poolAddress)).toString());
|
|
let integratedAddressBase58Prefix = config.poolServer.intAddressPrefix ? parseInt(config.poolServer.intAddressPrefix) : addressBase58Prefix + 1;
|
|
let subAddressBase58Prefix = config.poolServer.subAddressPrefix ? parseInt(config.poolServer.subAddressPrefix) : "N/A";
|
|
|
|
// Get address prefix
|
|
function getAddressPrefix(address) {
|
|
let addressBuffer = Buffer.from(address);
|
|
|
|
let addressPrefix = cnUtil.address_decode(addressBuffer);
|
|
if (addressPrefix) {
|
|
if (typeof addressPrefix === 'number')
|
|
addressPrefix = parseInt(addressPrefix)
|
|
else
|
|
addressPrefix = parseInt(addressPrefix.toString('hex'));
|
|
}
|
|
if (!addressPrefix && cnUtil.address_decode_integrated) {
|
|
addressPrefix = cnUtil.address_decode_integrated(addressBuffer);
|
|
if (addressPrefix) addressPrefix = parseInt(addressPrefix.toString());
|
|
}
|
|
|
|
return addressPrefix || null;
|
|
}
|
|
exports.getAddressPrefix = getAddressPrefix;
|
|
|
|
// Validate miner address
|
|
exports.validateMinerAddress = function(address) {
|
|
let addressPrefix = getAddressPrefix(address);
|
|
if (addressPrefix === addressBase58Prefix) return true;
|
|
else if (addressPrefix === integratedAddressBase58Prefix) return true;
|
|
else if (addressPrefix === subAddressBase58Prefix) return true;
|
|
else if (cnUtil.is_address_valid) {
|
|
return cnUtil.is_address_valid(Buffer.from(address)) || false
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function characterCount(string, char) {
|
|
let re = new RegExp(char,"gi")
|
|
let matches = string.match(re)
|
|
return matches === null ? 0 : matches.length;
|
|
}
|
|
exports.characterCount = characterCount
|
|
|
|
// Validate miner address
|
|
exports.validateChildMinerAddress = (address, index) => {
|
|
let childAddressBase58Prefix = parseInt(cnUtil.address_decode(Buffer.from(config.childPools[index].poolAddress)).toString());
|
|
let childIntegratedAddressBase58Prefix = config.poolServer.intChildAddressPrefix ? parseInt(config.childPools[index].intAddressPrefix) : childAddressBase58Prefix + 1;
|
|
|
|
let addressPrefix = getAddressPrefix(address);
|
|
if (addressPrefix === childAddressBase58Prefix) return true;
|
|
else if (addressPrefix === childIntegratedAddressBase58Prefix) return true;
|
|
return false;
|
|
}
|
|
|
|
// Return if value is an integrated address
|
|
exports.isIntegratedAddress = function(address) {
|
|
let addressPrefix = getAddressPrefix(address);
|
|
return (addressPrefix === integratedAddressBase58Prefix);
|
|
}
|
|
|
|
exports.determineRewardData = (value) => {
|
|
let calculatedData = {'address': value, 'rewardType': 'prop'}
|
|
if (/^solo:/i.test(value))
|
|
{
|
|
calculatedData['address'] = value.substr(5)
|
|
calculatedData['rewardType'] = 'solo'
|
|
return calculatedData
|
|
}
|
|
if (/^prop:/i.test(value))
|
|
{
|
|
calculatedData['address'] = value.substr(5)
|
|
calculatedData['rewardType'] = 'prop'
|
|
return calculatedData
|
|
}
|
|
return calculatedData
|
|
}
|
|
|
|
/**
|
|
* Cleanup special characters (fix for non latin characters)
|
|
**/
|
|
function cleanupSpecialChars(str) {
|
|
str = str.replace(/[ÀÁÂÃÄÅ]/g,"A");
|
|
str = str.replace(/[àáâãäå]/g,"a");
|
|
str = str.replace(/[ÈÉÊË]/g,"E");
|
|
str = str.replace(/[èéêë]/g,"e");
|
|
str = str.replace(/[ÌÎÏ]/g,"I");
|
|
str = str.replace(/[ìîï]/g,"i");
|
|
str = str.replace(/[ÒÔÖ]/g,"O");
|
|
str = str.replace(/[òôö]/g,"o");
|
|
str = str.replace(/[ÙÛÜ]/g,"U");
|
|
str = str.replace(/[ùûü]/g,"u");
|
|
return str.replace(/[^A-Za-z0-9\-\_+]/gi,'');
|
|
}
|
|
exports.cleanupSpecialChars = cleanupSpecialChars;
|
|
|
|
/**
|
|
* Get readable hashrate
|
|
**/
|
|
exports.getReadableHashRate = function(hashrate){
|
|
let i = 0;
|
|
let byteUnits = [' H', ' KH', ' MH', ' GH', ' TH', ' PH' ];
|
|
while (hashrate > 1000){
|
|
hashrate = hashrate / 1000;
|
|
i++;
|
|
}
|
|
return hashrate.toFixed(2) + byteUnits[i] + '/sec';
|
|
}
|
|
|
|
/**
|
|
* Get readable coins
|
|
**/
|
|
exports.getReadableCoins = function(coins, digits, withoutSymbol){
|
|
let coinDecimalPlaces = config.coinDecimalPlaces || config.coinUnits.toString().length - 1;
|
|
let amount = (parseInt(coins || 0) / config.coinUnits).toFixed(digits || coinDecimalPlaces);
|
|
return amount + (withoutSymbol ? '' : (' ' + config.symbol));
|
|
}
|
|
|
|
/**
|
|
* Generate unique id
|
|
**/
|
|
exports.uid = function(){
|
|
let min = 100000000000000;
|
|
let max = 999999999999999;
|
|
let id = Math.floor(Math.random() * (max - min + 1)) + min;
|
|
return id.toString();
|
|
};
|
|
|
|
/**
|
|
* Ring buffer
|
|
**/
|
|
exports.ringBuffer = function(maxSize){
|
|
let data = [];
|
|
let cursor = 0;
|
|
let isFull = false;
|
|
|
|
return {
|
|
append: function(x){
|
|
if (isFull){
|
|
data[cursor] = x;
|
|
cursor = (cursor + 1) % maxSize;
|
|
}
|
|
else{
|
|
data.push(x);
|
|
cursor++;
|
|
if (data.length === maxSize){
|
|
cursor = 0;
|
|
isFull = true;
|
|
}
|
|
}
|
|
},
|
|
avg: function(plusOne){
|
|
let sum = data.reduce(function(a, b){ return a + b }, plusOne || 0);
|
|
return sum / ((isFull ? maxSize : cursor) + (plusOne ? 1 : 0));
|
|
},
|
|
size: function(){
|
|
return isFull ? maxSize : cursor;
|
|
},
|
|
clear: function(){
|
|
data = [];
|
|
cursor = 0;
|
|
isFull = false;
|
|
}
|
|
};
|
|
};
|
|
|