Compare commits

..

4 Commits
master ... dev

Author SHA1 Message Date
Michael Polzer
0af3101931
Merge pull request #172 from lubuzzo/dev
Generate a new address after submit a block
2019-03-24 18:56:07 +01:00
lubuzzo
9b4b7dfac5 Fixed a issue when user explicity specify the address 2019-03-24 13:03:36 -03:00
lubuzzo
6f43936a76 Generate a new address after submit a block
- Pool will generate a new address on the startup and after a block be 
submitted
- So, pool owner will have a better privacity - once, every single block 
will be find by a different address
2019-03-24 12:33:58 -03:00
Michael Polzer
eec9fc9d67 Add support for p2sh, BIP32 and bech32 decoding (#147)
* Add Support for CHC Algo

* decode p2sh, BIP32 and native SegWit (bech32) keys for use in coinbase transactions
2018-05-26 19:37:31 -07:00
10 changed files with 92 additions and 113 deletions

View File

@ -50,8 +50,6 @@ Features
* ✓ __Quark__ (Quarkcoin [QRK]) * ✓ __Quark__ (Quarkcoin [QRK])
* ✓ __X11__ (Darkcoin [DRK], Hirocoin, Limecoin) * ✓ __X11__ (Darkcoin [DRK], Hirocoin, Limecoin)
* ✓ __X13__ (MaruCoin, BoostCoin) * ✓ __X13__ (MaruCoin, BoostCoin)
* ✓ __X16R__ (PexaCoin, RavenCoin)
* ✓ __X16RV2__ (PexaCoin, RavenCoin)
* ✓ __NIST5__ (Talkcoin) * ✓ __NIST5__ (Talkcoin)
* ✓ __Keccak__ (Maxcoin [MAX], HelixCoin, CryptoMeth, Galleon, 365coin, Slothcoin, BitcointalkCoin) * ✓ __Keccak__ (Maxcoin [MAX], HelixCoin, CryptoMeth, Galleon, 365coin, Slothcoin, BitcointalkCoin)
* ✓ __Skein__ (Skeincoin [SKC]) * ✓ __Skein__ (Skeincoin [SKC])

View File

@ -73,7 +73,6 @@ var algos = module.exports = global.algos = {
} }
} }
}, },
sha1: { sha1: {
hash: function(){ hash: function(){
return function(){ return function(){
@ -109,22 +108,6 @@ var algos = module.exports = global.algos = {
} }
} }
}, },
x16r: {
multiplier: Math.pow(2, 8),
hash: function(){
return function(){
return multiHashing.x16r.apply(this, arguments);
}
}
},
x16rv2: {
multiplier: Math.pow(2, 8),
hash: function(){
return function(){
return multiHashing.x16rv2.apply(this, arguments);
}
}
},
nist5: { nist5: {
hash: function(){ hash: function(){
return function(){ return function(){
@ -162,14 +145,6 @@ var algos = module.exports = global.algos = {
} }
} }
}, },
neoscrypt: {
multiplier: Math.pow(2, 5),
hash: function(){
return function(){
return multiHashing.neoscrypt.apply(this, arguments);
}
}
},
skein: { skein: {
hash: function(){ hash: function(){
return function(){ return function(){

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(jobId, rpcData, poolAddressScript, extraNoncePlaceholder, reward, txMessages, recipients){ var BlockTemplate = module.exports = function BlockTemplate(jobId, rpcData, poolAddressScript, extraNoncePlaceholder, reward, txMessages, recipients, network){
//private members //private members
@ -71,7 +71,8 @@ var BlockTemplate = module.exports = function BlockTemplate(jobId, rpcData, pool
extraNoncePlaceholder, extraNoncePlaceholder,
reward, reward,
txMessages, txMessages,
recipients recipients,
network
); );
this.serializeCoinbase = function(extraNonce1, extraNonce2){ this.serializeCoinbase = function(extraNonce1, extraNonce2){

View File

@ -37,7 +37,7 @@ function DaemonInterface(daemons, logger){
} }
function isOnline(callback){ function isOnline(callback){
cmd('getpeerinfo', [], function(results){ cmd('getnetworkinfo', [], function(results){
var allOnline = results.every(function(result){ var allOnline = results.every(function(result){
return !results.error; return !results.error;
}); });

View File

@ -69,6 +69,7 @@ var JobManager = module.exports = function JobManager(options){
var coinbaseHasher = (function(){ var coinbaseHasher = (function(){
switch(options.coin.algorithm){ switch(options.coin.algorithm){
case 'keccak': case 'keccak':
case 'blake':
case 'fugue': case 'fugue':
case 'groestl': case 'groestl':
if (options.coin.normalHashing === true) if (options.coin.normalHashing === true)
@ -89,6 +90,12 @@ var JobManager = module.exports = function JobManager(options){
return util.reverseBuffer(hashDigest.apply(this, arguments)); return util.reverseBuffer(hashDigest.apply(this, arguments));
}; };
} }
case 'scrypt-og':
if (options.coin.reward === 'POS') {
return function (d) {
return util.reverseBuffer(hashDigest.apply(this, arguments));
};
}
case 'scrypt-jane': case 'scrypt-jane':
if (options.coin.reward === 'POS') { if (options.coin.reward === 'POS') {
return function (d) { return function (d) {
@ -96,6 +103,7 @@ var JobManager = module.exports = function JobManager(options){
}; };
} }
case 'scrypt-n': case 'scrypt-n':
case 'sha1':
return function (d) { return function (d) {
return util.reverseBuffer(util.sha256d(d)); return util.reverseBuffer(util.sha256d(d));
}; };
@ -115,7 +123,8 @@ var JobManager = module.exports = function JobManager(options){
_this.extraNoncePlaceholder, _this.extraNoncePlaceholder,
options.coin.reward, options.coin.reward,
options.coin.txMessages, options.coin.txMessages,
options.recipients options.recipients,
options.network
); );
_this.currentJob = tmpBlockTemplate; _this.currentJob = tmpBlockTemplate;
@ -150,7 +159,8 @@ var JobManager = module.exports = function JobManager(options){
_this.extraNoncePlaceholder, _this.extraNoncePlaceholder,
options.coin.reward, options.coin.reward,
options.coin.txMessages, options.coin.txMessages,
options.recipients options.recipients,
options.network
); );
this.currentJob = tmpBlockTemplate; this.currentJob = tmpBlockTemplate;
@ -228,13 +238,8 @@ var JobManager = module.exports = function JobManager(options){
//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)){
blockHex = job.serializeBlock(headerBuffer, coinbaseBuffer).toString('hex'); blockHex = job.serializeBlock(headerBuffer, coinbaseBuffer).toString('hex');
if (options.coin.algorithm === 'blake' || options.coin.algorithm === 'neoscrypt') {
blockHash = util.reverseBuffer(util.sha256d(headerBuffer, nTime)).toString('hex');
}
else {
blockHash = blockHasher(headerBuffer, nTime).toString('hex'); blockHash = blockHasher(headerBuffer, nTime).toString('hex');
} }
}
else { else {
if (options.emitInvalidBlockHashes) if (options.emitInvalidBlockHashes)
blockHashInvalid = util.reverseBuffer(util.sha256d(headerBuffer)).toString('hex'); blockHashInvalid = util.reverseBuffer(util.sha256d(headerBuffer)).toString('hex');

View File

@ -188,9 +188,6 @@ var Peer = module.exports = function (options) {
_this.emit('connected'); _this.emit('connected');
} }
break; break;
case commands.version.toString():
SendMessage(commands.verack, Buffer.alloc(0));
break;
default: default:
break; break;
} }

View File

@ -20,6 +20,9 @@ var pool = module.exports = function pool(options, authorizeFn){
var _this = this; var _this = this;
var blockPollingIntervalId; var blockPollingIntervalId;
if (!(options.address)) {
_this.newAddressOnNewBlock = true;
}
var emitLog = function(text) { _this.emit('log', 'debug' , text); }; var emitLog = function(text) { _this.emit('log', 'debug' , text); };
var emitWarningLog = function(text) { _this.emit('log', 'warning', text); }; var emitWarningLog = function(text) { _this.emit('log', 'warning', text); };
@ -146,8 +149,7 @@ var pool = module.exports = function pool(options, authorizeFn){
var generateProgress = function(){ var generateProgress = function(){
var cmd = options.coin.hasGetInfo ? 'getinfo' : 'getblockchaininfo'; _this.daemon.cmd('getblockchaininfo', [], function(results) {
_this.daemon.cmd(cmd, [], function(results) {
var blockCount = results.sort(function (a, b) { var blockCount = results.sort(function (a, b) {
return b.response.blocks - a.response.blocks; return b.response.blocks - a.response.blocks;
})[0].response.blocks; })[0].response.blocks;
@ -224,7 +226,6 @@ var pool = module.exports = function pool(options, authorizeFn){
Coin daemons either use submitblock or getblocktemplate for submitting new blocks Coin daemons either use submitblock or getblocktemplate for submitting new blocks
*/ */
function SubmitBlock(blockHex, callback){ function SubmitBlock(blockHex, callback){
var rpcCommand, rpcArgs; var rpcCommand, rpcArgs;
if (options.hasSubmitMethod){ if (options.hasSubmitMethod){
rpcCommand = 'submitblock'; rpcCommand = 'submitblock';
@ -235,6 +236,16 @@ var pool = module.exports = function pool(options, authorizeFn){
rpcArgs = [{'mode': 'submit', 'data': blockHex}]; rpcArgs = [{'mode': 'submit', 'data': blockHex}];
} }
if (_this.newAddressOnNewBlock) {
_this.daemon.cmd('getnewaddress', [], function(results) {
options.poolAddressScript = (function(){
return util.addressToScript(options.network, results[0].response);
})();
options.address = results[0].response;
});
}
_this.daemon.cmd(rpcCommand, _this.daemon.cmd(rpcCommand,
rpcArgs, rpcArgs,
@ -274,7 +285,7 @@ var pool = module.exports = function pool(options, authorizeFn){
if (r.length === 40) if (r.length === 40)
rObj.script = util.miningKeyToScript(r); rObj.script = util.miningKeyToScript(r);
else else
rObj.script = util.addressToScript(r); rObj.script = util.addressToScript(options.network, r);
recipients.push(rObj); recipients.push(rObj);
options.feePercent += percent; options.feePercent += percent;
} }
@ -351,6 +362,12 @@ var pool = module.exports = function pool(options, authorizeFn){
}); });
_this.daemon.once('online', function(){ _this.daemon.once('online', function(){
if (options.address == false) {
_this.daemon.cmd('getnewaddress', [], function(results) {
options.address = results[0].response;
finishedCallback();
})
}
finishedCallback(); finishedCallback();
}).on('connectionFailed', function(error){ }).on('connectionFailed', function(error){
@ -370,15 +387,12 @@ var pool = module.exports = function pool(options, authorizeFn){
var batchRpcCalls = [ var batchRpcCalls = [
['validateaddress', [options.address]], ['validateaddress', [options.address]],
['getdifficulty', []], ['getdifficulty', []],
['getblockchaininfo', []],
['getnetworkinfo', []],
['getmininginfo', []], ['getmininginfo', []],
['submitblock', []] ['submitblock', []]
]; ];
if (options.coin.hasGetInfo) {
batchRpcCalls.push(['getinfo', []]);
} else {
batchRpcCalls.push(['getblockchaininfo', []], ['getnetworkinfo', []]);
}
_this.daemon.batchCmd(batchRpcCalls, function(error, results){ _this.daemon.batchCmd(batchRpcCalls, function(error, results){
if (error || !results){ if (error || !results){
emitErrorLog('Could not start pool, error with init batch RPC call: ' + JSON.stringify(error)); emitErrorLog('Could not start pool, error with init batch RPC call: ' + JSON.stringify(error));
@ -418,27 +432,24 @@ var pool = module.exports = function pool(options, authorizeFn){
return; return;
} }
options.testnet = (rpcResults.getblockchaininfo.chain === 'test') ? true : false;
options.network = (options.testnet ? options.coin.testnet : options.coin.mainnet);
options.poolAddressScript = (function(){ options.poolAddressScript = (function(){
switch(options.coin.reward){ switch(options.coin.reward){
case 'POS': case 'POS':
return util.pubkeyToScript(rpcResults.validateaddress.pubkey); return util.pubkeyToScript(rpcResults.validateaddress.pubkey);
case 'POW': case 'POW':
return util.addressToScript(rpcResults.validateaddress.address); return util.addressToScript(options.network, rpcResults.validateaddress.address);
} }
})(); })();
options.testnet = options.coin.hasGetInfo ? rpcResults.getinfo.testnet : (rpcResults.getblockchaininfo.chain === 'test') ? true : false; options.protocolVersion = rpcResults.getnetworkinfo.protocolversion;
options.protocolVersion = options.coin.hasGetInfo ? rpcResults.getinfo.protocolversion : rpcResults.getnetworkinfo.protocolversion;
var difficulty = options.coin.hasGetInfo ? rpcResults.getinfo.difficulty : rpcResults.getblockchaininfo.difficulty;
if (typeof(difficulty) == 'object') {
difficulty = difficulty['proof-of-work'];
}
options.initStats = { options.initStats = {
connections: (options.coin.hasGetInfo ? rpcResults.getinfo.connections : rpcResults.getnetworkinfo.connections), connections: rpcResults.getnetworkinfo.connections,
difficulty: difficulty * algos[options.coin.algorithm].multiplier, difficulty: rpcResults.getblockchaininfo.difficulty * algos[options.coin.algorithm].multiplier,
networkHashRate: rpcResults.getmininginfo.networkhashps networkHashRate: rpcResults.getmininginfo.networkhashps
}; };

View File

@ -123,7 +123,7 @@ For some (probably outdated and incorrect) documentation about whats kinda going
see: https://en.bitcoin.it/wiki/Protocol_specification#tx see: https://en.bitcoin.it/wiki/Protocol_specification#tx
*/ */
var generateOutputTransactions = function(poolRecipient, recipients, rpcData){ var generateOutputTransactions = function(poolRecipient, recipients, rpcData, network){
var reward = rpcData.coinbasevalue; var reward = rpcData.coinbasevalue;
var rewardToPool = reward; var rewardToPool = reward;
@ -141,7 +141,7 @@ if (rpcData.masternode && rpcData.superblock) {
reward -= payeeReward; reward -= payeeReward;
rewardToPool -= payeeReward; rewardToPool -= payeeReward;
var payeeScript = util.addressToScript(rpcData.masternode.payee); var payeeScript = util.addressToScript(network, rpcData.masternode.payee);
txOutputBuffers.push(Buffer.concat([ txOutputBuffers.push(Buffer.concat([
util.packInt64LE(payeeReward), util.packInt64LE(payeeReward),
util.varIntBuffer(payeeScript.length), util.varIntBuffer(payeeScript.length),
@ -155,7 +155,7 @@ if (rpcData.masternode && rpcData.superblock) {
reward -= payeeReward; reward -= payeeReward;
rewardToPool -= payeeReward; rewardToPool -= payeeReward;
var payeeScript = util.addressToScript(rpcData.superblock[i].payee); var payeeScript = util.addressToScript(network, rpcData.superblock[i].payee);
txOutputBuffers.push(Buffer.concat([ txOutputBuffers.push(Buffer.concat([
util.packInt64LE(payeeReward), util.packInt64LE(payeeReward),
util.varIntBuffer(payeeScript.length), util.varIntBuffer(payeeScript.length),
@ -177,7 +177,7 @@ if (rpcData.payee) {
reward -= payeeReward; reward -= payeeReward;
rewardToPool -= payeeReward; rewardToPool -= payeeReward;
var payeeScript = util.addressToScript(rpcData.payee); var payeeScript = util.addressToScript(network, rpcData.payee);
txOutputBuffers.push(Buffer.concat([ txOutputBuffers.push(Buffer.concat([
util.packInt64LE(payeeReward), util.packInt64LE(payeeReward),
util.varIntBuffer(payeeScript.length), util.varIntBuffer(payeeScript.length),
@ -222,7 +222,7 @@ if (rpcData.payee) {
}; };
exports.CreateGeneration = function(rpcData, publicKey, extraNoncePlaceholder, reward, txMessages, recipients){ exports.CreateGeneration = function(rpcData, publicKey, extraNoncePlaceholder, reward, txMessages, recipients, network){
var txInputsCount = 1; var txInputsCount = 1;
var txOutputsCount = 1; var txOutputsCount = 1;
@ -245,7 +245,7 @@ exports.CreateGeneration = function(rpcData, publicKey, extraNoncePlaceholder, r
var scriptSigPart1 = Buffer.concat([ var scriptSigPart1 = Buffer.concat([
util.serializeNumber(rpcData.height), util.serializeNumber(rpcData.height),
new Buffer([]), new Buffer(rpcData.coinbaseaux.flags, 'hex'),
util.serializeNumber(Date.now() / 1000 | 0), util.serializeNumber(Date.now() / 1000 | 0),
new Buffer([extraNoncePlaceholder.length]) new Buffer([extraNoncePlaceholder.length])
]); ]);
@ -272,7 +272,7 @@ exports.CreateGeneration = function(rpcData, publicKey, extraNoncePlaceholder, r
*/ */
var outputTransactions = generateOutputTransactions(publicKey, recipients, rpcData); var outputTransactions = generateOutputTransactions(publicKey, recipients, rpcData, network);
var p2 = Buffer.concat([ var p2 = Buffer.concat([
scriptSigPart2, scriptSigPart2,

View File

@ -2,6 +2,7 @@ var crypto = require('crypto');
var base58 = require('base58-native'); var base58 = require('base58-native');
var bignum = require('bignum'); var bignum = require('bignum');
var bitcoin = require('bitcoinjs-lib');
exports.addressFromEx = function(exAddress, ripdm160Key){ exports.addressFromEx = function(exAddress, ripdm160Key){
@ -261,26 +262,16 @@ exports.miningKeyToScript = 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.addressToScript = function(addr){ exports.addressToScript = function(network, addr){
var decoded = base58.decode(addr); if (typeof network !== 'undefined' && network !== null){
return bitcoin.address.toOutputScript(addr, network);
if (decoded.length != 25){ } else {
console.error('invalid address length for ' + addr); return Buffer.concat([new Buffer([0x76, 0xa9, 0x14]), bitcoin.address.fromBase58Check(addr).hash, new Buffer([0x88, 0xac])]);
throw new Error();
} }
if (!decoded){
console.error('base58 decode failed for ' + addr);
throw new Error();
}
var pubkey = decoded.slice(1,-4);
return Buffer.concat([new Buffer([0x76, 0xa9, 0x14]), pubkey, new Buffer([0x88, 0xac])]);
}; };
exports.getReadableHashRateString = function(hashrate){ exports.getReadableHashRateString = function(hashrate){
var i = -1; var i = -1;
var byteUnits = [ ' KH', ' MH', ' GH', ' TH', ' PH' ]; var byteUnits = [ ' KH', ' MH', ' GH', ' TH', ' PH' ];

View File

@ -12,9 +12,9 @@
"litecoin", "litecoin",
"scrypt" "scrypt"
], ],
"homepage": "https://github.com/ranchimall/node-stratum-pool", "homepage": "https://github.com/zone117x/node-stratum-pool",
"bugs": { "bugs": {
"url": "https://github.com/ranchimall/node-stratum-pool/issues" "url": "https://github.com/zone117x/node-stratum-pool/issues"
}, },
"license": "GPL-2.0", "license": "GPL-2.0",
"author": "Matthew Little", "author": "Matthew Little",
@ -25,11 +25,12 @@
"main": "lib/index.js", "main": "lib/index.js",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/ranchimall/node-stratum-pool.git" "url": "https://github.com/zone117x/node-stratum-pool.git"
}, },
"dependencies": { "dependencies": {
"multi-hashing": "git://github.com/zone117x/node-multi-hashing.git", "multi-hashing": "git://github.com/zone117x/node-multi-hashing.git",
"bignum": "0.12.1", "bitcoinjs-lib": "*",
"bignum": "*",
"base58-native": "*", "base58-native": "*",
"async": "*" "async": "*"
}, },