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

This commit is contained in:
Matt 2014-04-20 11:56:00 -06:00
parent 9a42211c38
commit 50ffb00440
5 changed files with 58 additions and 57 deletions

View File

@ -2,13 +2,12 @@ var bignum = require('bignum');
var multiHashing = require('multi-hashing'); var multiHashing = require('multi-hashing');
var util = require('./util.js'); var util = require('./util.js');
var diff1 = global.diff1 = bignum('00000000ffff0000000000000000000000000000000000000000000000000000', 16); var diff1 = global.diff1 = 0x00000000ffff0000000000000000000000000000000000000000000000000000;
var algos = module.exports = global.algos = { var algos = module.exports = global.algos = {
sha256: { sha256: {
//Uncomment diff if you want to use hardcoded truncated diff //Uncomment diff if you want to use hardcoded truncated diff
//diff: '00000000ffff0000000000000000000000000000000000000000000000000000', //diff: '00000000ffff0000000000000000000000000000000000000000000000000000',
multiplier: Math.pow(2, 32),
hash: function(){ hash: function(){
return function(){ return function(){
return util.sha256d.apply(this, arguments); return util.sha256d.apply(this, arguments);
@ -60,7 +59,6 @@ var algos = module.exports = global.algos = {
} }
}, },
x11: { x11: {
multiplier: Math.pow(2, 32),
hash: function(){ hash: function(){
return function(){ return function(){
return multiHashing.x11.apply(this, arguments); return multiHashing.x11.apply(this, arguments);
@ -68,7 +66,6 @@ var algos = module.exports = global.algos = {
} }
}, },
quark: { quark: {
multiplier: Math.pow(2, 32),
hash: function(){ hash: function(){
return function(){ return function(){
return multiHashing.quark.apply(this, arguments); return multiHashing.quark.apply(this, arguments);
@ -76,7 +73,7 @@ var algos = module.exports = global.algos = {
} }
}, },
keccak: { keccak: {
multiplier: Math.pow(2, 24), multiplier: Math.pow(2, 8),
hash: function(coinConfig){ hash: function(coinConfig){
if (coinConfig.normalHashing === true) { if (coinConfig.normalHashing === true) {
return function (data, nTimeInt) { return function (data, nTimeInt) {
@ -91,7 +88,7 @@ var algos = module.exports = global.algos = {
} }
}, },
blake: { blake: {
multiplier: Math.pow(2, 24), multiplier: Math.pow(2, 8),
hash: function(){ hash: function(){
return function(){ return function(){
return multiHashing.blake.apply(this, arguments); return multiHashing.blake.apply(this, arguments);
@ -99,7 +96,7 @@ var algos = module.exports = global.algos = {
} }
}, },
skein: { skein: {
multiplier: Math.pow(2, 24), multiplier: Math.pow(2, 8),
hash: function(){ hash: function(){
return function(){ return function(){
return multiHashing.skein.apply(this, arguments); return multiHashing.skein.apply(this, arguments);
@ -107,7 +104,7 @@ var algos = module.exports = global.algos = {
} }
}, },
fugue: { fugue: {
multiplier: Math.pow(2, 24), multiplier: Math.pow(2, 8),
hash: function(){ hash: function(){
return function(){ return function(){
return multiHashing.fugue.apply(this, arguments); return multiHashing.fugue.apply(this, arguments);
@ -142,7 +139,10 @@ var algos = module.exports = global.algos = {
for (var algo in 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); algos[algo].maxDiff = bignum(algos[algo].diff, 16);
} }
else if (algos[algo].shift){ else if (algos[algo].shift){
@ -155,5 +155,5 @@ for (var algo in algos){
} }
else{ else{
algos[algo].maxDiff = diff1; algos[algo].maxDiff = diff1;
} }*/
} }

View File

@ -9,7 +9,7 @@ var util = require('./util.js');
* The BlockTemplate class holds a single job. * The BlockTemplate class holds a single job.
* and provides several methods to validate and submit it to the daemon coin * 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 //private members
@ -45,7 +45,7 @@ var BlockTemplate = module.exports = function BlockTemplate(maxDifficulty, jobId
bignum(rpcData.target, 16) : bignum(rpcData.target, 16) :
util.bignumFromBitsHex(rpcData.bits); 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.prevHashReversed = util.reverseByteOrder(new Buffer(rpcData.previousblockhash, 'hex')).toString('hex');
this.transactionData = Buffer.concat(rpcData.transactions.map(function(tx){ this.transactionData = Buffer.concat(rpcData.transactions.map(function(tx){

View File

@ -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 req = http.request(options, function(res) {
var data = ''; var data = '';
res.setEncoding('utf8'); res.setEncoding('utf8');
res.on('data', function (chunk) { res.on('data', function (chunk) {
data += chunk; data += chunk;
}); });
res.on('end', function(){ res.on('end', function(){
parseJson(res, data);
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);
}); });
}); });

View File

@ -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 * - 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 * - 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 //private members
@ -53,6 +53,7 @@ var JobManager = module.exports = function JobManager(maxDifficulty, options){
var _this = this; var _this = this;
var jobCounter = new JobCounter(); var jobCounter = new JobCounter();
var shareMultiplier = algos[options.coin.algorithm].multiplier;
//public members //public members
@ -102,7 +103,6 @@ var JobManager = module.exports = function JobManager(maxDifficulty, options){
this.updateCurrentJob = function(publicKey){ this.updateCurrentJob = function(publicKey){
var tmpBlockTemplate = new blockTemplate( var tmpBlockTemplate = new blockTemplate(
maxDifficulty,
jobCounter.next(), jobCounter.next(),
_this.currentJob.rpcData, _this.currentJob.rpcData,
publicKey, publicKey,
@ -149,7 +149,6 @@ var JobManager = module.exports = function JobManager(maxDifficulty, options){
lastTransactionUpdateCheck = Date.now(); lastTransactionUpdateCheck = Date.now();
var tmpBlockTemplate = new blockTemplate( var tmpBlockTemplate = new blockTemplate(
maxDifficulty,
jobCounter.next(), jobCounter.next(),
rpcData, rpcData,
publicKey, publicKey,
@ -234,11 +233,9 @@ var JobManager = module.exports = function JobManager(maxDifficulty, options){
var blockHash; var blockHash;
var blockHex; var blockHex;
var shareDiff = difficulty < 1 ? var shareDiff = diff1 / headerBigNum.toNumber() * shareMultiplier;
maxDifficulty.toNumber() / headerBigNum.toNumber() :
maxDifficulty.div(headerBigNum).toNumber();
var blockDiffAdjusted = maxDifficulty.toNumber() / job.target.toNumber(); var blockDiffAdjusted = job.difficulty * shareMultiplier;
//Check if share is a block candidate (matched network difficulty) //Check if share is a block candidate (matched network difficulty)
if (job.target.ge(headerBigNum)){ if (job.target.ge(headerBigNum)){
@ -280,7 +277,7 @@ var JobManager = module.exports = function JobManager(maxDifficulty, options){
height: job.rpcData.height, height: job.rpcData.height,
reward: job.rpcData.coinbasevalue, reward: job.rpcData.coinbasevalue,
difficulty: difficulty, difficulty: difficulty,
shareDiff: shareDiff, shareDiff: shareDiff.toFixed(8),
blockDiff : blockDiffAdjusted, blockDiff : blockDiffAdjusted,
blockDiffActual: job.difficulty, blockDiffActual: job.difficulty,
blockHash: blockHash, blockHash: blockHash,

View File

@ -50,7 +50,7 @@ var pool = module.exports = function pool(options, authorizeFn){
//Which number to use as dividend when converting difficulty to target //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(){ this.start = function(){
@ -85,15 +85,17 @@ var pool = module.exports = function pool(options, authorizeFn){
var portWarnings = []; var portWarnings = [];
var networkDiffAdjusted = options.initStats.difficulty;
Object.keys(options.ports).forEach(function(port){ Object.keys(options.ports).forEach(function(port){
var portDiff = options.ports[port].diff; var portDiff = options.ports[port].diff;
if (options.initStats.difficulty < portDiff) if (networkDiffAdjusted < portDiff)
portWarnings.push('port ' + port + ' w/ diff ' + portDiff); portWarnings.push('port ' + port + ' w/ diff ' + portDiff);
}); });
//Only let the first fork show synced status or the log wil look flooded with it //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')) { 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 '); + portWarnings.join(' and ');
emitWarningLog(warnMessage); emitWarningLog(warnMessage);
} }
@ -113,11 +115,11 @@ var pool = module.exports = function pool(options, authorizeFn){
return; return;
} }
var infoLines = [startMessage, 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, 'Detected Reward Type:\t' + options.coin.reward,
'Current Block Height:\t' + _this.jobManager.currentJob.rpcData.height, 'Current Block Height:\t' + _this.jobManager.currentJob.rpcData.height,
'Current Connect Peers:\t' + options.initStats.connections, '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 Difficulty:\t' + options.initStats.difficulty,
'Network Hash Rate:\t' + util.getReadableHashRateString(options.initStats.networkHashRate), 'Network Hash Rate:\t' + util.getReadableHashRateString(options.initStats.networkHashRate),
'Stratum Port(s):\t' + _this.options.initStats.stratumPorts.join(', ') 'Stratum Port(s):\t' + _this.options.initStats.stratumPorts.join(', ')
@ -263,7 +265,7 @@ var pool = module.exports = function pool(options, authorizeFn){
function SetupJobManager(){ function SetupJobManager(){
_this.jobManager = new jobManager(maxDifficulty, options); _this.jobManager = new jobManager(options);
_this.jobManager.on('newBlock', function(blockTemplate){ _this.jobManager.on('newBlock', function(blockTemplate){
//Check if stratumServer has been initialized yet //Check if stratumServer has been initialized yet
@ -397,7 +399,7 @@ var pool = module.exports = function pool(options, authorizeFn){
options.initStats = { options.initStats = {
connections: rpcResults.getinfo.connections, connections: rpcResults.getinfo.connections,
difficulty: rpcResults.getinfo.difficulty, difficulty: rpcResults.getinfo.difficulty * algos[options.coin.algorithm].multiplier,
networkHashRate: rpcResults.getmininginfo.networkhashps networkHashRate: rpcResults.getmininginfo.networkhashps
}; };