Fixed duplicate shares on vardiff difficulty update. Added more comments.
This commit is contained in:
parent
87bab0dfd1
commit
897dadbf11
@ -16,10 +16,10 @@ var blockTemplate = require('./blockTemplate.js');
|
|||||||
var ExtraNonceCounter = function(){
|
var ExtraNonceCounter = function(){
|
||||||
var instanceId = 31;
|
var instanceId = 31;
|
||||||
var counter = instanceId << 27;
|
var counter = instanceId << 27;
|
||||||
var size = util.packUInt32BE(counter).length; //binpack.packUInt32(counter, 'big').length;
|
var size = util.packUInt32BE(counter).length;
|
||||||
|
|
||||||
this.next = function(){
|
this.next = function(){
|
||||||
var extraNonce = util.packUInt32BE(counter++);//binpack.packUInt32(counter++, 'big');
|
var extraNonce = util.packUInt32BE(counter++);
|
||||||
return extraNonce.toString('hex');
|
return extraNonce.toString('hex');
|
||||||
};
|
};
|
||||||
this.size = function(){
|
this.size = function(){
|
||||||
@ -54,6 +54,7 @@ var JobManager = module.exports = function JobManager(options){
|
|||||||
|
|
||||||
var _this = this;
|
var _this = this;
|
||||||
var jobCounter = new JobCounter();
|
var jobCounter = new JobCounter();
|
||||||
|
//var jobs = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It only checks if the blockTemplate is already in our jobs list.
|
* It only checks if the blockTemplate is already in our jobs list.
|
||||||
@ -68,8 +69,19 @@ var JobManager = module.exports = function JobManager(options){
|
|||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*var newBlock = true;
|
||||||
|
for(var job in jobs){
|
||||||
|
if (jobs[job].rpcData.previousblockhash === prevBlockHash) {
|
||||||
|
newBlock = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newBlock;*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Which number to use as dividend when converting difficulty to target
|
||||||
var diffDividend = (function(){
|
var diffDividend = (function(){
|
||||||
switch(options.algorithm){
|
switch(options.algorithm){
|
||||||
case 'sha256':
|
case 'sha256':
|
||||||
@ -82,6 +94,8 @@ var JobManager = module.exports = function JobManager(options){
|
|||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
//On initialization lets figure out which hashing algorithm to use
|
||||||
var hashDigest = (function(){
|
var hashDigest = (function(){
|
||||||
switch(options.algorithm){
|
switch(options.algorithm){
|
||||||
case 'sha256':
|
case 'sha256':
|
||||||
@ -103,7 +117,6 @@ var JobManager = module.exports = function JobManager(options){
|
|||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//public members
|
//public members
|
||||||
|
|
||||||
@ -125,6 +138,8 @@ var JobManager = module.exports = function JobManager(options){
|
|||||||
options.txMessages
|
options.txMessages
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//jobs[tmpBlockTemplate.jobId] = tmpBlockTemplate;
|
||||||
|
|
||||||
this.currentJob = tmpBlockTemplate;
|
this.currentJob = tmpBlockTemplate;
|
||||||
_this.emit('newBlock', tmpBlockTemplate);
|
_this.emit('newBlock', tmpBlockTemplate);
|
||||||
}
|
}
|
||||||
@ -132,7 +147,6 @@ var JobManager = module.exports = function JobManager(options){
|
|||||||
|
|
||||||
this.processShare = function(jobId, difficulty, extraNonce1, extraNonce2, nTime, nonce, ipAddress, workerName){
|
this.processShare = function(jobId, difficulty, extraNonce1, extraNonce2, nTime, nonce, ipAddress, workerName){
|
||||||
|
|
||||||
|
|
||||||
var shareError = function(error){
|
var shareError = function(error){
|
||||||
_this.emit('share', {
|
_this.emit('share', {
|
||||||
job: jobId,
|
job: jobId,
|
||||||
@ -150,7 +164,9 @@ var JobManager = module.exports = function JobManager(options){
|
|||||||
return shareError([20, 'incorrect size of extranonce2']);
|
return shareError([20, 'incorrect size of extranonce2']);
|
||||||
|
|
||||||
var job = this.currentJob;
|
var job = this.currentJob;
|
||||||
if ( job.jobId != jobId ) {
|
//var job = jobs[jobId];
|
||||||
|
|
||||||
|
if (typeof job === 'undefined' || job.jobId != jobId ) {
|
||||||
return shareError([21, 'job not found']);
|
return shareError([21, 'job not found']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
20
lib/pool.js
20
lib/pool.js
@ -52,7 +52,25 @@ var pool = module.exports = function pool(options, authorizeFn){
|
|||||||
RequestDifficulty(function(){});
|
RequestDifficulty(function(){});
|
||||||
}).on('newDifficulty', function(client, newDiff){
|
}).on('newDifficulty', function(client, newDiff){
|
||||||
client.sendDifficulty(newDiff);
|
client.sendDifficulty(newDiff);
|
||||||
client.sendMiningJob(_this.jobManager.currentJob.getJobParams());
|
|
||||||
|
/*
|
||||||
|
Disabled this line of code as it will because it will force the miner
|
||||||
|
to restart and submit duplicate shares. The stratum-python sends out a
|
||||||
|
mining.notify but rolls the jobID and sets "clean jobs" to false.
|
||||||
|
Meaning that the worker will only start on the new work once it
|
||||||
|
exhausts its current nonce range. But if the miner were to start the
|
||||||
|
new job, the shares would be invalidated since stratum-python doesn't
|
||||||
|
insert the new jobID that the share-limiter generated into the jobs
|
||||||
|
array. Also, since the new work is only sent with a new jobID but with
|
||||||
|
the same extranonce as the last job, the shares will be duplicate
|
||||||
|
anyway. Perhaps this bug has gone unnoticed because of how likely it
|
||||||
|
is for a miner to exhaust the nonce range before new work is sent.
|
||||||
|
|
||||||
|
So lets only send a new difficulty, and the worker will use it when
|
||||||
|
it receives a new job when the block template updates.
|
||||||
|
*/
|
||||||
|
//client.sendMiningJob(_this.jobManager.currentJob.getJobParams());
|
||||||
|
|
||||||
});
|
});
|
||||||
emitLog("system", "VarDiff enabled and setup");
|
emitLog("system", "VarDiff enabled and setup");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -118,10 +118,7 @@ var Generation = exports.Generation = function Generation(rpcData, publicKey, ex
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
This function creates the generation transaction that accepts the reward for
|
This function creates the generation transaction that accepts the reward for
|
||||||
successfully mining a new block. Creating this function required tons of trial
|
successfully mining a new block.
|
||||||
and error and reversing existing pool server code. I went to write a good comment
|
|
||||||
describing how it works in detail but at this point I don't even know..
|
|
||||||
|
|
||||||
For some (probably outdated and incorrect) documentation about whats kinda going on here,
|
For some (probably outdated and incorrect) documentation about whats kinda going on here,
|
||||||
see: https://en.bitcoin.it/wiki/Protocol_specification#tx
|
see: https://en.bitcoin.it/wiki/Protocol_specification#tx
|
||||||
*/
|
*/
|
||||||
@ -139,6 +136,11 @@ exports.CreateGeneration = function(rpcData, publicKey, extraNoncePlaceholder, r
|
|||||||
var txInPrevOutIndex = Math.pow(2, 32) - 1;
|
var txInPrevOutIndex = Math.pow(2, 32) - 1;
|
||||||
var txInSequence = 0;
|
var txInSequence = 0;
|
||||||
|
|
||||||
|
//Only required for POS coins
|
||||||
|
var txTimestamp = reward === 'POS' ?
|
||||||
|
util.packUInt32LE(rpcData.curtime) : new Buffer([]);
|
||||||
|
|
||||||
|
//For coins that support/require transaction comments
|
||||||
var txComment = txMessages === true ?
|
var txComment = txMessages === true ?
|
||||||
util.serializeString('https://github.com/zone117x/node-stratum') :
|
util.serializeString('https://github.com/zone117x/node-stratum') :
|
||||||
new Buffer([]);
|
new Buffer([]);
|
||||||
@ -153,10 +155,9 @@ exports.CreateGeneration = function(rpcData, publicKey, extraNoncePlaceholder, r
|
|||||||
|
|
||||||
var scriptSigPart2 = util.serializeString('/nodeStratum/');
|
var scriptSigPart2 = util.serializeString('/nodeStratum/');
|
||||||
|
|
||||||
|
|
||||||
var p1 = Buffer.concat([
|
var p1 = Buffer.concat([
|
||||||
util.packUInt32LE(txVersion),
|
util.packUInt32LE(txVersion),
|
||||||
reward === 'POS' ? util.packUInt32LE(rpcData.curtime) : new Buffer([]),
|
txTimestamp,
|
||||||
util.varIntBuffer(txInputsCount),
|
util.varIntBuffer(txInputsCount),
|
||||||
|
|
||||||
//transaction input
|
//transaction input
|
||||||
@ -166,6 +167,13 @@ exports.CreateGeneration = function(rpcData, publicKey, extraNoncePlaceholder, r
|
|||||||
scriptSigPart1
|
scriptSigPart1
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
The generation transaction must be split at the extranonce (which located in the transaction input
|
||||||
|
scriptSig). Miners send us unique extranonces that we use to join the two parts in attempt to create
|
||||||
|
a valid share and/or block.
|
||||||
|
*/
|
||||||
|
|
||||||
var p2 = Buffer.concat([
|
var p2 = Buffer.concat([
|
||||||
scriptSigPart2,
|
scriptSigPart2,
|
||||||
util.packUInt32LE(txInSequence),
|
util.packUInt32LE(txInSequence),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user