Fixed bugs that happen when banning is disabled. Attempted to add keccak (maxcoin).
This commit is contained in:
parent
898301fba8
commit
41b121ab56
@ -3,10 +3,7 @@ var crypto = require('crypto');
|
|||||||
|
|
||||||
var bignum = require('bignum');
|
var bignum = require('bignum');
|
||||||
|
|
||||||
var scrypt = require('scrypt256-hash');
|
|
||||||
var quark = require('quark-hash');
|
|
||||||
var scryptJane = require('scrypt-jane-hash');
|
|
||||||
var x11 = require('x11-hash');
|
|
||||||
|
|
||||||
var util = require('./util.js');
|
var util = require('./util.js');
|
||||||
var blockTemplate = require('./blockTemplate.js');
|
var blockTemplate = require('./blockTemplate.js');
|
||||||
@ -48,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(options){
|
var JobManager = module.exports = function JobManager(maxDifficulty, hashDigest, options){
|
||||||
|
|
||||||
|
|
||||||
//private members
|
//private members
|
||||||
@ -56,77 +53,6 @@ var JobManager = module.exports = function JobManager(options){
|
|||||||
var _this = this;
|
var _this = this;
|
||||||
var jobCounter = new JobCounter();
|
var jobCounter = new JobCounter();
|
||||||
|
|
||||||
//Which number to use as dividend when converting difficulty to target
|
|
||||||
var maxDifficulty = bignum((function(){
|
|
||||||
switch(options.coin.algorithm){
|
|
||||||
case 'sha256':
|
|
||||||
case 'skein':
|
|
||||||
return '00000000ffff0000000000000000000000000000000000000000000000000000';
|
|
||||||
case 'scrypt':
|
|
||||||
case 'scrypt-jane':
|
|
||||||
case 'x11':
|
|
||||||
return '0000ffff00000000000000000000000000000000000000000000000000000000';
|
|
||||||
case 'quark':
|
|
||||||
return '0000ffff00000000000000000000000000000000000000000000000000000000';
|
|
||||||
case 'max':
|
|
||||||
return 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000'
|
|
||||||
}
|
|
||||||
})(), 16);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//On initialization lets figure out which hashing algorithm to use
|
|
||||||
var hashDigest = (function(){
|
|
||||||
switch(options.coin.algorithm){
|
|
||||||
case 'sha256':
|
|
||||||
return function(){
|
|
||||||
return util.doublesha.apply(this, arguments);
|
|
||||||
}
|
|
||||||
case 'scrypt':
|
|
||||||
return function(){
|
|
||||||
return scrypt.digest.apply(this, arguments);
|
|
||||||
}
|
|
||||||
case 'scrypt-jane':
|
|
||||||
return function(){
|
|
||||||
return scryptJane.digest.apply(this, arguments);
|
|
||||||
}
|
|
||||||
case 'quark':
|
|
||||||
return function(){
|
|
||||||
return quark.digest.apply(this, arguments);
|
|
||||||
}
|
|
||||||
case 'x11':
|
|
||||||
return function(){
|
|
||||||
return x11.digest.apply(this, arguments);
|
|
||||||
}
|
|
||||||
case 'skein':
|
|
||||||
return function(data){
|
|
||||||
|
|
||||||
/*var dataString = data.slice(0, 80).toString('ascii');
|
|
||||||
var skeinHashed = skein(dataString);
|
|
||||||
|
|
||||||
var hash1 = crypto.createHash('sha256');
|
|
||||||
hash1.update(new Buffer(skeinHashed, 'hex'));
|
|
||||||
hash1 = hash1.digest();
|
|
||||||
|
|
||||||
return hash1;*/
|
|
||||||
|
|
||||||
//https://github.com/cruzrr/insanehash
|
|
||||||
//https://github.com/Crypto-Expert/stratum-mining/blob/master/lib/skein.py
|
|
||||||
}
|
|
||||||
case 'max':
|
|
||||||
return function(){
|
|
||||||
//Keccak hash
|
|
||||||
//https://github.com/phusion/node-sha3
|
|
||||||
//https://github.com/Prydie/maxcoin-hash-python
|
|
||||||
//https://github.com/ahmedbodi/stratum-mining-maxcoin/blob/master/lib/template_registry.py
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return function(){
|
|
||||||
console.log('Hashing algorithm ' + options.coin.algorithm + ' not supported');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
|
|
||||||
//public members
|
//public members
|
||||||
|
|
||||||
|
|||||||
89
lib/pool.js
89
lib/pool.js
@ -1,5 +1,7 @@
|
|||||||
var events = require('events');
|
var events = require('events');
|
||||||
var async = require('async');
|
var async = require('async');
|
||||||
|
var bignum = require('bignum');
|
||||||
|
|
||||||
|
|
||||||
var varDiff = require('./varDiff.js');
|
var varDiff = require('./varDiff.js');
|
||||||
var daemon = require('./daemon.js');
|
var daemon = require('./daemon.js');
|
||||||
@ -8,6 +10,11 @@ var stratum = require('./stratum.js');
|
|||||||
var jobManager = require('./jobManager.js');
|
var jobManager = require('./jobManager.js');
|
||||||
var util = require('./util.js');
|
var util = require('./util.js');
|
||||||
|
|
||||||
|
var scrypt = require('scrypt256-hash');
|
||||||
|
var quark = require('quark-hash');
|
||||||
|
var scryptJane = require('scrypt-jane-hash');
|
||||||
|
var x11 = require('x11-hash');
|
||||||
|
var keccak = require('keccak-hash');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main pool object. It emits the following events:
|
* Main pool object. It emits the following events:
|
||||||
@ -35,6 +42,74 @@ var pool = module.exports = function pool(options, authorizeFn){
|
|||||||
var emitWarningLog = function(text) { _this.emit('log', 'warning', text); };
|
var emitWarningLog = function(text) { _this.emit('log', 'warning', text); };
|
||||||
var emitErrorLog = function(text) { _this.emit('log', 'error' , text); };
|
var emitErrorLog = function(text) { _this.emit('log', 'error' , text); };
|
||||||
|
|
||||||
|
|
||||||
|
//Which number to use as dividend when converting difficulty to target
|
||||||
|
var maxDifficulty = bignum((function(){
|
||||||
|
switch(options.coin.algorithm){
|
||||||
|
case 'sha256':
|
||||||
|
case 'skein':
|
||||||
|
return '00000000ffff0000000000000000000000000000000000000000000000000000';
|
||||||
|
case 'scrypt':
|
||||||
|
case 'scrypt-jane':
|
||||||
|
case 'x11':
|
||||||
|
case 'quark':
|
||||||
|
case 'keccak':
|
||||||
|
return '0000ffff00000000000000000000000000000000000000000000000000000000';
|
||||||
|
}
|
||||||
|
})(), 16);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//On initialization lets figure out which hashing algorithm to use
|
||||||
|
var hashDigest = (function(){
|
||||||
|
switch(options.coin.algorithm){
|
||||||
|
case 'sha256':
|
||||||
|
return function(){
|
||||||
|
return util.doublesha.apply(this, arguments);
|
||||||
|
}
|
||||||
|
case 'scrypt':
|
||||||
|
return function(){
|
||||||
|
return scrypt.digest.apply(this, arguments);
|
||||||
|
}
|
||||||
|
case 'scrypt-jane':
|
||||||
|
return function(){
|
||||||
|
return scryptJane.digest.apply(this, arguments);
|
||||||
|
}
|
||||||
|
case 'quark':
|
||||||
|
return function(){
|
||||||
|
return quark.digest.apply(this, arguments);
|
||||||
|
}
|
||||||
|
case 'x11':
|
||||||
|
return function(){
|
||||||
|
return x11.digest.apply(this, arguments);
|
||||||
|
}
|
||||||
|
case 'keccak':
|
||||||
|
return function(){
|
||||||
|
return keccak.digest.apply(this, arguments);
|
||||||
|
}
|
||||||
|
case 'skein':
|
||||||
|
return function(data){
|
||||||
|
|
||||||
|
/*var dataString = data.slice(0, 80).toString('ascii');
|
||||||
|
var skeinHashed = skein(dataString);
|
||||||
|
|
||||||
|
var hash1 = crypto.createHash('sha256');
|
||||||
|
hash1.update(new Buffer(skeinHashed, 'hex'));
|
||||||
|
hash1 = hash1.digest();
|
||||||
|
|
||||||
|
return hash1;*/
|
||||||
|
|
||||||
|
//https://github.com/cruzrr/insanehash
|
||||||
|
//https://github.com/Crypto-Expert/stratum-mining/blob/master/lib/skein.py
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return function(){
|
||||||
|
console.log('Hashing algorithm ' + options.coin.algorithm + ' not supported');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
this.start = function(){
|
this.start = function(){
|
||||||
emitLog('Starting pool for ' + options.coin.name + ' [' + options.coin.symbol.toUpperCase() + ']');
|
emitLog('Starting pool for ' + options.coin.name + ' [' + options.coin.symbol.toUpperCase() + ']');
|
||||||
SetupJobManager();
|
SetupJobManager();
|
||||||
@ -115,7 +190,7 @@ var pool = module.exports = function pool(options, authorizeFn){
|
|||||||
|
|
||||||
function SetupJobManager(){
|
function SetupJobManager(){
|
||||||
|
|
||||||
_this.jobManager = new jobManager(options);
|
_this.jobManager = new jobManager(maxDifficulty, hashDigest, 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
|
||||||
@ -291,9 +366,15 @@ var pool = module.exports = function pool(options, authorizeFn){
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
publicKeyBuffer = options.coin.reward === 'POW' ?
|
publicKeyBuffer = (function(){
|
||||||
util.script_to_address(results.addressInfo.address) :
|
switch(options.coin.reward){
|
||||||
util.script_to_pubkey(results.addressInfo.pubkey);
|
case 'POS':
|
||||||
|
return util.pubkeyToScript(results.addressInfo.pubkey);
|
||||||
|
case 'POW':
|
||||||
|
if (options.coin.algorithm)
|
||||||
|
return util.addressToScript(results.addressInfo.address);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
var networkType = results.info.testnet ? 'testnet' : 'live blockchain';
|
var networkType = results.info.testnet ? 'testnet' : 'live blockchain';
|
||||||
|
|
||||||
|
|||||||
@ -36,7 +36,7 @@ var StratumClient = function(options){
|
|||||||
|
|
||||||
this.shares = {valid: 0, invalid: 0};
|
this.shares = {valid: 0, invalid: 0};
|
||||||
|
|
||||||
var considerBan = !banning.enabled ? function(){} : function(shareValid){
|
var considerBan = (!banning || !banning.enabled) ? function(){} : function(shareValid){
|
||||||
if (shareValid === true) _this.shares.valid++;
|
if (shareValid === true) _this.shares.valid++;
|
||||||
else _this.shares.invalid++;
|
else _this.shares.invalid++;
|
||||||
var totalShares = _this.shares.valid + _this.shares.invalid;
|
var totalShares = _this.shares.valid + _this.shares.invalid;
|
||||||
@ -292,7 +292,7 @@ var StratumServer = exports.Server = function StratumServer(ports, connectionTim
|
|||||||
//private members
|
//private members
|
||||||
|
|
||||||
var socketTimeout = connectionTimeout * 1000;
|
var socketTimeout = connectionTimeout * 1000;
|
||||||
var bannedMS = banning.time * 1000;
|
var bannedMS = banning ? banning.time * 1000 : null;
|
||||||
|
|
||||||
var _this = this;
|
var _this = this;
|
||||||
var stratumClients = {};
|
var stratumClients = {};
|
||||||
@ -301,7 +301,7 @@ var StratumServer = exports.Server = function StratumServer(ports, connectionTim
|
|||||||
var bannedIPs = {};
|
var bannedIPs = {};
|
||||||
|
|
||||||
//Interval to look through bannedIPs for old bans and remove them in order to prevent a memory leak
|
//Interval to look through bannedIPs for old bans and remove them in order to prevent a memory leak
|
||||||
var purgeOldBans = !banning.enabled ? null : setInterval(function(){
|
var purgeOldBans = (!banning || !banning.enabled) ? null : setInterval(function(){
|
||||||
for (ip in bannedIPs){
|
for (ip in bannedIPs){
|
||||||
var banTime = bannedIPs[ip];
|
var banTime = bannedIPs[ip];
|
||||||
if (Date.now() - banTime > banning.time)
|
if (Date.now() - banTime > banning.time)
|
||||||
@ -310,7 +310,7 @@ var StratumServer = exports.Server = function StratumServer(ports, connectionTim
|
|||||||
}, 1000 * banning.purgeInterval);
|
}, 1000 * banning.purgeInterval);
|
||||||
|
|
||||||
this.handleNewClient = function (socket) {
|
this.handleNewClient = function (socket) {
|
||||||
if (banning.enabled && socket.remoteAddress in bannedIPs){
|
if (banning && banning.enabled && socket.remoteAddress in bannedIPs){
|
||||||
var bannedTime = bannedIPs[socket.remoteAddress];
|
var bannedTime = bannedIPs[socket.remoteAddress];
|
||||||
if ((Date.now() - bannedTime) < bannedMS){
|
if ((Date.now() - bannedTime) < bannedMS){
|
||||||
socket.end();
|
socket.end();
|
||||||
|
|||||||
53
lib/util.js
53
lib/util.js
@ -236,34 +236,47 @@ exports.range = function(start, stop, step){
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
exports.address_to_pubkeyhash = function(addr){
|
exports.getVersionByte = function(addr){
|
||||||
addr = base58.decode(addr);
|
return base58.decode(addr)[0];
|
||||||
|
};
|
||||||
|
|
||||||
if (addr.length != 25){
|
exports.addressToPubkey = function(addr){
|
||||||
console.log('invalid address length for ' + addr);
|
|
||||||
throw 'invalid address length';
|
var decoded = base58.decode(addr);
|
||||||
|
|
||||||
|
if (decoded.length != 25){
|
||||||
|
console.error('invalid address length for ' + addr);
|
||||||
|
throw new Error();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!addr)
|
if (!decoded){
|
||||||
return null;
|
console.error('base58 decode failed for ' + addr);
|
||||||
|
throw new Error();
|
||||||
|
}
|
||||||
|
|
||||||
var ver = addr[0];
|
/* We already do rpc.validateaddress so we don't need this
|
||||||
var cksumA = addr.slice(-4);
|
var ver = decoded[0];
|
||||||
var cksumB = exports.doublesha(addr.slice(0, -4)).slice(0, 4);
|
var cksumA = decoded.slice(-4);
|
||||||
|
var cksumB = exports.doublesha(decoded.slice(0, -4)).slice(0, 4);
|
||||||
|
|
||||||
if (cksumA.toString('hex') != cksumB.toString('hex'))
|
if (cksumA.toString('hex') != cksumB.toString('hex')){
|
||||||
throw 'checksum did not match';
|
console.error('checksum did not match for ' + addr)
|
||||||
|
//throw new Error();
|
||||||
|
}*/
|
||||||
|
|
||||||
return [ver, addr.slice(1,-4)];
|
return decoded.slice(1,-4);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
For POS coins - used to format wallet address for use in generation transaction's output
|
For POS coins - used to format wallet address for use in generation transaction's output
|
||||||
*/
|
*/
|
||||||
exports.script_to_pubkey = function(key){
|
exports.pubkeyToScript = function(key){
|
||||||
if (key.length === 66) key = new Buffer(key, 'hex');
|
if (key.length === 66) key = new Buffer(key, 'hex');
|
||||||
if (key.length !== 33) throw 'Invalid address';
|
if (key.length !== 33){
|
||||||
|
console.error('Invalid pubkey: ' + key);
|
||||||
|
throw new Error();
|
||||||
|
}
|
||||||
var pubkey = new Buffer(35);
|
var pubkey = new Buffer(35);
|
||||||
pubkey[0] = 0x21;
|
pubkey[0] = 0x21;
|
||||||
pubkey[34] = 0xac;
|
pubkey[34] = 0xac;
|
||||||
@ -275,12 +288,8 @@ exports.script_to_pubkey = function(key){
|
|||||||
/*
|
/*
|
||||||
For POW coins - used to format wallet address for use in generation transaction's output
|
For POW coins - used to format wallet address for use in generation transaction's output
|
||||||
*/
|
*/
|
||||||
exports.script_to_address = function(addr){
|
|
||||||
var d = exports.address_to_pubkeyhash(addr)
|
|
||||||
if (!d)
|
|
||||||
throw "invalid address";
|
|
||||||
|
|
||||||
var ver = d[0];
|
exports.addressToScript = function(addr){
|
||||||
var pubkeyhash = d[1];
|
var pubkey = exports.addressToPubkey(addr);
|
||||||
return Buffer.concat([new Buffer([0x76, 0xa9, 0x14]), pubkeyhash, new Buffer([0x88, 0xac])]);
|
return Buffer.concat([new Buffer([0x76, 0xa9, 0x14]), pubkey, new Buffer([0x88, 0xac])]);
|
||||||
};
|
};
|
||||||
@ -32,6 +32,7 @@
|
|||||||
"scrypt-jane-hash": "https://github.com/zone117x/node-scrypt-jane-hash/archive/master.tar.gz",
|
"scrypt-jane-hash": "https://github.com/zone117x/node-scrypt-jane-hash/archive/master.tar.gz",
|
||||||
"quark-hash": "https://github.com/zone117x/node-quark-hash/archive/master.tar.gz",
|
"quark-hash": "https://github.com/zone117x/node-quark-hash/archive/master.tar.gz",
|
||||||
"x11-hash": "https://github.com/zone117x/node-x11-hash/archive/master.tar.gz",
|
"x11-hash": "https://github.com/zone117x/node-x11-hash/archive/master.tar.gz",
|
||||||
|
"keccak-hash": "https://github.com/zone117x/node-keccak-hash/archive/master.tar.gz",
|
||||||
"bignum": "*",
|
"bignum": "*",
|
||||||
"base58-native": "*",
|
"base58-native": "*",
|
||||||
"async": "*"
|
"async": "*"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user