From 50ffb004405153477f10aa36627508791398853d Mon Sep 17 00:00:00 2001 From: Matt Date: Sun, 20 Apr 2014 11:56:00 -0600 Subject: [PATCH] Removed concept of 'maxdiff' for different algos - replaced with "share multiplier" which is more accurate. Removed use of bignum for determining difficulty as JS number seem to be precise enough --- lib/algoProperties.js | 20 +++++++------- lib/blockTemplate.js | 4 +-- lib/daemon.js | 62 ++++++++++++++++++++++--------------------- lib/jobManager.js | 13 ++++----- lib/pool.js | 16 ++++++----- 5 files changed, 58 insertions(+), 57 deletions(-) diff --git a/lib/algoProperties.js b/lib/algoProperties.js index 9e51843..6148359 100644 --- a/lib/algoProperties.js +++ b/lib/algoProperties.js @@ -2,13 +2,12 @@ var bignum = require('bignum'); var multiHashing = require('multi-hashing'); var util = require('./util.js'); -var diff1 = global.diff1 = bignum('00000000ffff0000000000000000000000000000000000000000000000000000', 16); +var diff1 = global.diff1 = 0x00000000ffff0000000000000000000000000000000000000000000000000000; var algos = module.exports = global.algos = { sha256: { //Uncomment diff if you want to use hardcoded truncated diff //diff: '00000000ffff0000000000000000000000000000000000000000000000000000', - multiplier: Math.pow(2, 32), hash: function(){ return function(){ return util.sha256d.apply(this, arguments); @@ -60,7 +59,6 @@ var algos = module.exports = global.algos = { } }, x11: { - multiplier: Math.pow(2, 32), hash: function(){ return function(){ return multiHashing.x11.apply(this, arguments); @@ -68,7 +66,6 @@ var algos = module.exports = global.algos = { } }, quark: { - multiplier: Math.pow(2, 32), hash: function(){ return function(){ return multiHashing.quark.apply(this, arguments); @@ -76,7 +73,7 @@ var algos = module.exports = global.algos = { } }, keccak: { - multiplier: Math.pow(2, 24), + multiplier: Math.pow(2, 8), hash: function(coinConfig){ if (coinConfig.normalHashing === true) { return function (data, nTimeInt) { @@ -91,7 +88,7 @@ var algos = module.exports = global.algos = { } }, blake: { - multiplier: Math.pow(2, 24), + multiplier: Math.pow(2, 8), hash: function(){ return function(){ return multiHashing.blake.apply(this, arguments); @@ -99,7 +96,7 @@ var algos = module.exports = global.algos = { } }, skein: { - multiplier: Math.pow(2, 24), + multiplier: Math.pow(2, 8), hash: function(){ return function(){ return multiHashing.skein.apply(this, arguments); @@ -107,7 +104,7 @@ var algos = module.exports = global.algos = { } }, fugue: { - multiplier: Math.pow(2, 24), + multiplier: Math.pow(2, 8), hash: function(){ return function(){ return multiHashing.fugue.apply(this, arguments); @@ -142,7 +139,10 @@ var algos = module.exports = global.algos = { for (var algo in algos){ - if (algos[algo].diff){ + if (!algos[algo].multiplier) + algos[algo].multiplier = 1; + + /*if (algos[algo].diff){ algos[algo].maxDiff = bignum(algos[algo].diff, 16); } else if (algos[algo].shift){ @@ -155,5 +155,5 @@ for (var algo in algos){ } else{ algos[algo].maxDiff = diff1; - } + }*/ } \ No newline at end of file diff --git a/lib/blockTemplate.js b/lib/blockTemplate.js index 1fe4501..8f7aecf 100644 --- a/lib/blockTemplate.js +++ b/lib/blockTemplate.js @@ -9,7 +9,7 @@ var util = require('./util.js'); * The BlockTemplate class holds a single job. * and provides several methods to validate and submit it to the daemon coin **/ -var BlockTemplate = module.exports = function BlockTemplate(maxDifficulty, jobId, rpcData, publicKey, extraNoncePlaceholder, reward, txMessages){ +var BlockTemplate = module.exports = function BlockTemplate(jobId, rpcData, publicKey, extraNoncePlaceholder, reward, txMessages){ //private members @@ -45,7 +45,7 @@ var BlockTemplate = module.exports = function BlockTemplate(maxDifficulty, jobId bignum(rpcData.target, 16) : util.bignumFromBitsHex(rpcData.bits); - this.difficulty = parseFloat((diff1.toNumber() / this.target.toNumber()).toFixed(9)); + this.difficulty = parseFloat((diff1 / this.target.toNumber()).toFixed(9)); this.prevHashReversed = util.reverseByteOrder(new Buffer(rpcData.previousblockhash, 'hex')).toString('hex'); this.transactionData = Buffer.concat(rpcData.transactions.map(function(tx){ diff --git a/lib/daemon.js b/lib/daemon.js index 5c9dabc..5075c65 100644 --- a/lib/daemon.js +++ b/lib/daemon.js @@ -56,43 +56,45 @@ function DaemonInterface(options){ } }; + var parseJson = function(res, data){ + var dataJson; + var parsingError; + + try{ + dataJson = JSON.parse(data); + + } + catch(e){ + if (res.statusCode === 401){ + parsingError = 'unauthorized'; + _this.emit('error', 'Invalid RPC username or password'); + } + else if (data.indexOf(':-nan,') !== -1){ + data = data.replace(/:-nan,/g, ":0,"); + parseJson(res, data); + return; + } + else{ + parsingError = e; + _this.emit('error', 'could not parse rpc data with request of: ' + jsonData + + ' on instance ' + instance.index + ' data: ' + data + ' Error ' + JSON.stringify(parsingError)); + } + } + if (typeof(dataJson) !== 'undefined'){ + callback(dataJson.error, dataJson); + } + else + callback(parsingError); + }; + var req = http.request(options, function(res) { var data = ''; res.setEncoding('utf8'); res.on('data', function (chunk) { data += chunk; - }); res.on('end', function(){ - - var dataJson; - var parsingError; - - //if (data.indexOf(':-nan,') !== -1){ - // data = data.replace(/:-nan,/g, ":0,") - //} - - try{ - dataJson = JSON.parse(data); - - } - catch(e){ - if (res.statusCode === 401){ - parsingError = 'unauthorized'; - _this.emit('error', 'Invalid RPC username or password'); - } - else{ - parsingError = e; - _this.emit('error', 'could not parse rpc data with request of: ' + jsonData + - ' on instance ' + instance.index + ' data: ' + data + ' Error ' + JSON.stringify(parsingError)); - } - } - if (typeof(dataJson) !== 'undefined'){ - callback(dataJson.error, dataJson); - } - else - callback(parsingError); - + parseJson(res, data); }); }); diff --git a/lib/jobManager.js b/lib/jobManager.js index 32ed375..0ceaef0 100644 --- a/lib/jobManager.js +++ b/lib/jobManager.js @@ -45,7 +45,7 @@ var JobCounter = function(){ * - newBlock(blockTemplate) - When a new block (previously unknown to the JobManager) is added, use this event to broadcast new jobs * - share(shareData, blockHex) - When a worker submits a share. It will have blockHex if a block was found **/ -var JobManager = module.exports = function JobManager(maxDifficulty, options){ +var JobManager = module.exports = function JobManager(options){ //private members @@ -53,6 +53,7 @@ var JobManager = module.exports = function JobManager(maxDifficulty, options){ var _this = this; var jobCounter = new JobCounter(); + var shareMultiplier = algos[options.coin.algorithm].multiplier; //public members @@ -102,7 +103,6 @@ var JobManager = module.exports = function JobManager(maxDifficulty, options){ this.updateCurrentJob = function(publicKey){ var tmpBlockTemplate = new blockTemplate( - maxDifficulty, jobCounter.next(), _this.currentJob.rpcData, publicKey, @@ -149,7 +149,6 @@ var JobManager = module.exports = function JobManager(maxDifficulty, options){ lastTransactionUpdateCheck = Date.now(); var tmpBlockTemplate = new blockTemplate( - maxDifficulty, jobCounter.next(), rpcData, publicKey, @@ -234,11 +233,9 @@ var JobManager = module.exports = function JobManager(maxDifficulty, options){ var blockHash; var blockHex; - var shareDiff = difficulty < 1 ? - maxDifficulty.toNumber() / headerBigNum.toNumber() : - maxDifficulty.div(headerBigNum).toNumber(); + var shareDiff = diff1 / headerBigNum.toNumber() * shareMultiplier; - var blockDiffAdjusted = maxDifficulty.toNumber() / job.target.toNumber(); + var blockDiffAdjusted = job.difficulty * shareMultiplier; //Check if share is a block candidate (matched network difficulty) if (job.target.ge(headerBigNum)){ @@ -280,7 +277,7 @@ var JobManager = module.exports = function JobManager(maxDifficulty, options){ height: job.rpcData.height, reward: job.rpcData.coinbasevalue, difficulty: difficulty, - shareDiff: shareDiff, + shareDiff: shareDiff.toFixed(8), blockDiff : blockDiffAdjusted, blockDiffActual: job.difficulty, blockHash: blockHash, diff --git a/lib/pool.js b/lib/pool.js index 00b077d..6c579e2 100644 --- a/lib/pool.js +++ b/lib/pool.js @@ -50,7 +50,7 @@ var pool = module.exports = function pool(options, authorizeFn){ //Which number to use as dividend when converting difficulty to target - var maxDifficulty = algos[options.coin.algorithm].maxDiff; + //var maxDifficulty = algos[options.coin.algorithm].maxDiff; this.start = function(){ @@ -85,15 +85,17 @@ var pool = module.exports = function pool(options, authorizeFn){ var portWarnings = []; + var networkDiffAdjusted = options.initStats.difficulty; + Object.keys(options.ports).forEach(function(port){ var portDiff = options.ports[port].diff; - if (options.initStats.difficulty < portDiff) + if (networkDiffAdjusted < portDiff) portWarnings.push('port ' + port + ' w/ diff ' + portDiff); }); //Only let the first fork show synced status or the log wil look flooded with it if (portWarnings.length > 0 && (!process.env.forkId || process.env.forkId === '0')) { - var warnMessage = 'Network diff of ' + options.initStats.difficulty + ' is lower than ' + var warnMessage = 'Network diff of ' + networkDiffAdjusted + ' is lower than ' + portWarnings.join(' and '); emitWarningLog(warnMessage); } @@ -113,11 +115,11 @@ var pool = module.exports = function pool(options, authorizeFn){ return; } var infoLines = [startMessage, - 'Network Connected:\t' + (options.testnet ? 'Testnet' : 'Live Blockchain'), + 'Network Connected:\t' + (options.testnet ? 'Testnet' : 'Mainnet'), 'Detected Reward Type:\t' + options.coin.reward, 'Current Block Height:\t' + _this.jobManager.currentJob.rpcData.height, 'Current Connect Peers:\t' + options.initStats.connections, - 'Current Block Diff:\t' + _this.jobManager.currentJob.difficulty, + 'Current Block Diff:\t' + _this.jobManager.currentJob.difficulty * algos[options.coin.algorithm].multiplier, 'Network Difficulty:\t' + options.initStats.difficulty, 'Network Hash Rate:\t' + util.getReadableHashRateString(options.initStats.networkHashRate), 'Stratum Port(s):\t' + _this.options.initStats.stratumPorts.join(', ') @@ -263,7 +265,7 @@ var pool = module.exports = function pool(options, authorizeFn){ function SetupJobManager(){ - _this.jobManager = new jobManager(maxDifficulty, options); + _this.jobManager = new jobManager(options); _this.jobManager.on('newBlock', function(blockTemplate){ //Check if stratumServer has been initialized yet @@ -397,7 +399,7 @@ var pool = module.exports = function pool(options, authorizeFn){ options.initStats = { connections: rpcResults.getinfo.connections, - difficulty: rpcResults.getinfo.difficulty, + difficulty: rpcResults.getinfo.difficulty * algos[options.coin.algorithm].multiplier, networkHashRate: rpcResults.getmininginfo.networkhashps };