Updated to support new Darkcoin masternode features

This commit is contained in:
Matt 2014-05-06 20:29:15 -06:00
parent 9821694812
commit a06ba67ab3
6 changed files with 86 additions and 56 deletions

View File

@ -304,7 +304,6 @@ Listen to pool events
ip: '71.33.19.37', //ip address of client
worker: 'matt.worker1', //stratum worker name
height: 443795, //block height
poolReward: 4900000000, //the number of satoshis sent to the configured pool address
blockReward: 5000000000, //the number of satoshis received as payment for solving this block
difficulty: 64, //stratum worker difficulty
shareDiff: 78, //actual difficulty of the share

View File

@ -28,26 +28,23 @@ var BlockTemplate = module.exports = function BlockTemplate(jobId, rpcData, pool
return [null].concat(txHashes);
}
function getVoteData(){
if (!rpcData.masternode_payments) return new Buffer([]);
return Buffer.concat(
[util.varIntBuffer(rpcData.votes.length)].concat(
rpcData.votes.map(function (vt) {
return new Buffer(vt, 'hex');
})
)
);
}
//public members
this.rpcData = rpcData;
this.jobId = jobId;
this.poolReward = (function(){
var pReward = rpcData.coinbasevalue;
for (var i = 0; i < recipients.length; i++){
var recipientReward = Math.floor(recipients[i].percent * rpcData.coinbasevalue);
pReward -= recipientReward;
}
return pReward;
})();
//Use the 'target' field if available, but some daemons only return the 'bits' field
/*this.target = rpcData.target ?
bignum.fromBuffer(new Buffer(rpcData.target, 'hex')) :
util.bignumFromBits(rpcData.bits);*/
this.target = rpcData.target ?
bignum(rpcData.target, 16) :
@ -55,6 +52,10 @@ var BlockTemplate = module.exports = function BlockTemplate(jobId, rpcData, pool
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){
return new Buffer(tx.data, 'hex');
@ -98,9 +99,13 @@ var BlockTemplate = module.exports = function BlockTemplate(jobId, rpcData, pool
this.serializeBlock = function(header, coinbase){
return Buffer.concat([
header,
util.varIntBuffer(this.rpcData.transactions.length + 1),
coinbase,
this.transactionData,
getVoteData(),
//POS coins require a zero byte appended to block which the daemon replaces with the signature
new Buffer(reward === 'POS' ? [0] : [])
]);

View File

@ -13,16 +13,19 @@ var async = require('async');
* - 'password': password for the rpc interface of the coin
**/
function DaemonInterface(options){
function DaemonInterface(daemons, logger){
//private members
var _this = this;
this.options = options;
logger = logger || function(severity, message){
console.log(severity + ': ' + message);
};
var instances = (function(){
for (var i = 0; i < options.length; i++)
options[i]['index'] = i;
return options;
for (var i = 0; i < daemons.length; i++)
daemons[i]['index'] = i;
return daemons;
})();
@ -58,33 +61,28 @@ function DaemonInterface(options){
var parseJson = function(res, data){
var dataJson;
var parsingError;
if (res.statusCode === 401){
logger('error', 'Unauthorized RPC access - invalid RPC username or password');
return;
}
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,");
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));
}
logger('error', 'Could not parse rpc data from daemon instance ' + instance.index
+ '\nRequest Data: ' + jsonData
+ '\nReponse Data: ' + data);
}
if (typeof(dataJson) !== 'undefined'){
if (dataJson)
callback(dataJson.error, dataJson, data);
}
else
callback(parsingError);
};
var req = http.request(options, function(res) {

View File

@ -286,7 +286,6 @@ var JobManager = module.exports = function JobManager(options){
worker: workerName,
height: job.rpcData.height,
blockReward: job.rpcData.coinbasevalue,
poolReward: job.poolReward,
difficulty: difficulty,
shareDiff: shareDiff.toFixed(8),
blockDiff : blockDiffAdjusted,

View File

@ -8,6 +8,10 @@ var stratum = require('./stratum.js');
var jobManager = require('./jobManager.js');
var util = require('./util.js');
process.on('uncaughtException', function(err) {
console.log(err.stack);
throw err;
});
var pool = module.exports = function pool(options, authorizeFn){
@ -235,17 +239,21 @@ var pool = module.exports = function pool(options, authorizeFn){
_this.daemon.cmd(rpcCommand,
rpcArgs,
function(results){
results.forEach(function(result){
if (result.error)
for (var i = 0; i < results.length; i++){
var result = results[i];
if (result.error) {
emitErrorLog('rpc error with daemon instance ' +
result.instance.index + ' when submitting block with ' + rpcCommand + ' ' +
JSON.stringify(result.error)
result.instance.index + ' when submitting block with ' + rpcCommand + ' ' +
JSON.stringify(result.error)
);
else
emitLog('Submitted Block using ' + rpcCommand + ' to daemon instance ' +
result.instance.index
);
});
return;
}
else if (result.response === 'rejected') {
emitErrorLog('Daemon instance ' + result.instance.index + ' rejected a supposedly valid block');
return;
}
}
emitLog('Submitted Block using ' + rpcCommand + ' successfully to daemon instance(s)');
callback();
}
);
@ -338,7 +346,9 @@ var pool = module.exports = function pool(options, authorizeFn){
return;
}
_this.daemon = new daemon.interface(options.daemons);
_this.daemon = new daemon.interface(options.daemons, function(severity, message){
_this.emit('log', severity , message);
});
_this.daemon.once('online', function(){
finishedCallback();

View File

@ -123,18 +123,35 @@ For some (probably outdated and incorrect) documentation about whats kinda going
see: https://en.bitcoin.it/wiki/Protocol_specification#tx
*/
var generateOutputTransactions = function(poolRecipient, recipients, reward){
var generateOutputTransactions = function(poolRecipient, recipients, rpcData){
var totalOutputs = 1;
var reward = rpcData.coinbasevalue;
var rewardToPool = reward;
var txOutputBuffers = [];
var totalToRecipients = 0;
if (rpcData.payee) {
var payeeReward = Math.ceil(reward / 10);
reward -= payeeReward;
rewardToPool -= payeeReward;
var payeeScript = util.addressToScript(rpcData.payee);
txOutputBuffers.push(Buffer.concat([
util.packInt64LE(payeeReward),
util.varIntBuffer(payeeScript.length),
payeeScript
]));
}
for (var i = 0; i < recipients.length; i++){
var recipientReward = Math.floor(recipients[i].percent * reward);
totalToRecipients += recipientReward;
totalOutputs++;
rewardToPool -= recipientReward;
txOutputBuffers.push(Buffer.concat([
util.packInt64LE(recipientReward),
util.varIntBuffer(recipients[i].script.length),
@ -142,7 +159,6 @@ var generateOutputTransactions = function(poolRecipient, recipients, reward){
]));
}
var rewardToPool = reward - totalToRecipients;
txOutputBuffers.push(Buffer.concat([
util.packInt64LE(rewardToPool),
@ -151,7 +167,7 @@ var generateOutputTransactions = function(poolRecipient, recipients, reward){
]));
return Buffer.concat([
util.varIntBuffer(totalOutputs),
util.varIntBuffer(txOutputBuffers.length),
Buffer.concat(txOutputBuffers)
]);
@ -207,13 +223,16 @@ exports.CreateGeneration = function(rpcData, publicKey, extraNoncePlaceholder, r
a valid share and/or block.
*/
var outputTransactions = generateOutputTransactions(publicKey, recipients, rpcData);
var p2 = Buffer.concat([
scriptSigPart2,
util.packUInt32LE(txInSequence),
//end transaction input
//transaction output
generateOutputTransactions(publicKey, recipients, rpcData.coinbasevalue),
outputTransactions,
//end transaction ouput
util.packUInt32LE(txLockTime),