Added initial vardiff. Needs testing...
This commit is contained in:
parent
8e3b28cea3
commit
13b04ab509
31
lib/pool.js
31
lib/pool.js
@ -1,5 +1,7 @@
|
||||
var events = require('events');
|
||||
var async = require('async');
|
||||
|
||||
var varDiff = require('./varDifff.js');
|
||||
var daemon = require('./daemon.js');
|
||||
var stratum = require('./stratum.js');
|
||||
var jobManager = require('./jobManager.js');
|
||||
@ -22,6 +24,7 @@ var util = require('./util.js');
|
||||
var pool = module.exports = function pool(options, authorizeFn){
|
||||
|
||||
this.options = options;
|
||||
|
||||
var _this = this;
|
||||
var publicKeyBuffer;
|
||||
|
||||
@ -32,10 +35,34 @@ var pool = module.exports = function pool(options, authorizeFn){
|
||||
|
||||
(function Init(){
|
||||
SetupJobManager();
|
||||
SetupVarDiff();
|
||||
SetupDaemonInterface();
|
||||
})();
|
||||
|
||||
|
||||
function SetupVarDiff(){
|
||||
_this.varDiff = new varDifff(options.varDiff, options.difficulty);
|
||||
_this.varDiff.on('difficultyRequest', function(){
|
||||
emitLog('varDiff', 'Difficulty requested for vardiff');
|
||||
if (_this.stratumServer)
|
||||
RequestDifficulty(function(){});
|
||||
});
|
||||
}
|
||||
|
||||
function RequestDifficulty(callback){
|
||||
_this.daemon.cmd('getdifficulty',
|
||||
[],
|
||||
function(error, result){
|
||||
if (error) {
|
||||
emitErrorLog('getdifficulty', 'Error requesting difficulty from daemon for vardiff');
|
||||
} else {
|
||||
_this.varDiff.setNetworkDifficulty(result);
|
||||
callback(error, result);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
Coin daemons either use submitblock or getblocktemplate for submitting new blocks
|
||||
*/
|
||||
@ -108,6 +135,7 @@ var pool = module.exports = function pool(options, authorizeFn){
|
||||
_this.daemon = new daemon.interface(options.daemon);
|
||||
_this.daemon.on('online', function(){
|
||||
async.parallel({
|
||||
difficulty: RequestDifficulty,
|
||||
addressInfo: function(callback){
|
||||
_this.daemon.cmd('validateaddress',
|
||||
[options.address],
|
||||
@ -178,6 +206,9 @@ var pool = module.exports = function pool(options, authorizeFn){
|
||||
emitLog('system','Stratum server started on port ' + options.stratumPort);
|
||||
_this.emit('started');
|
||||
}).on('client.connected', function(client){
|
||||
|
||||
_this.varDiff.manageClient(client);
|
||||
|
||||
client.on('subscription', function(params, resultCallback){
|
||||
|
||||
var extraNonce = _this.jobManager.extraNonceCounter.next();
|
||||
|
||||
128
lib/varDifff.js
Normal file
128
lib/varDifff.js
Normal file
@ -0,0 +1,128 @@
|
||||
var events = require('events');
|
||||
|
||||
/*
|
||||
|
||||
Vardiff ported from stratum-mining share-limiter
|
||||
https://github.com/ahmedbodi/stratum-mining/blob/master/mining/basic_share_limiter.py
|
||||
|
||||
*/
|
||||
|
||||
|
||||
function RingBuffer(maxSize){
|
||||
var data = [];
|
||||
var cursor = 0;
|
||||
var isFull = false;
|
||||
this.append = function(x){
|
||||
if (isFull){
|
||||
data[cursor] = x;
|
||||
cursor = (cursor + 1) % maxSize;
|
||||
}
|
||||
else{
|
||||
data.push(x);
|
||||
cursor++;
|
||||
if (data.length === maxSize){
|
||||
cursor = 0;
|
||||
isFull = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
this.avg = function(){
|
||||
var total = data.reduce(function(a, b){
|
||||
return a + b;
|
||||
});
|
||||
return total / (isFull ? maxSize : cursor);
|
||||
};
|
||||
this.size = function(){
|
||||
return isFull ? maxSize : cursor;
|
||||
};
|
||||
this.clear = function(){
|
||||
data = [];
|
||||
cursor = 0;
|
||||
isFull = false;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
var varDiff = module.exports = function varDiff(options, poolDifficulty){
|
||||
|
||||
var _this = this;
|
||||
|
||||
if (!options.enabled){
|
||||
return;
|
||||
}
|
||||
|
||||
var networkDifficulty;
|
||||
var bufferSize = options.retargetTime / options.targetTime * 4;
|
||||
var variance = options.targetTime * (options.variancePercent / 100);
|
||||
var tMin = options.targetTime - variance;
|
||||
var tMax = options.targetTime + variance;
|
||||
|
||||
this.setNetworkDifficulty = function(diff){
|
||||
networkDifficulty = diff;
|
||||
};
|
||||
|
||||
setInterval(function(){
|
||||
_this.emit('difficultyRequest');
|
||||
}, options.daemonDiffUpdateFrequency * 1000);
|
||||
|
||||
this.manageClient = function(client){
|
||||
var lastTs;
|
||||
var lastRtc;
|
||||
var timeBuffer;
|
||||
|
||||
client.on('submit', function(){
|
||||
|
||||
var ts = Date.now() / 1000;
|
||||
|
||||
if (!lastRtc){
|
||||
lastRtc = ts - options.retargetTime / 2;
|
||||
lastTs = ts;
|
||||
timeBuffer = new RingBuffer(bufferSize);
|
||||
console.log('first time share vardiff');
|
||||
return;
|
||||
}
|
||||
|
||||
timeBuffer.append(ts - lastTs);
|
||||
lastTs = ts;
|
||||
|
||||
if ((ts - lastRtc) < options.retargetTime && timeBuffer.size() > 0){
|
||||
console.log('do not retarget');
|
||||
return;
|
||||
}
|
||||
|
||||
lastRtc = ts;
|
||||
var avg = timeBuffer.avg();
|
||||
|
||||
if (avg < 1)
|
||||
avg = 1;
|
||||
|
||||
var ddiff = (client.difficulty * (options.targetTime / avg)) - client.difficulty;
|
||||
|
||||
if (avg > tMax && client.difficulty > options.minDifficulty){
|
||||
if (ddiff > -1)
|
||||
ddiff = -1;
|
||||
if (ddiff + client.difficulty < poolDifficulty)
|
||||
ddiff = options.minDifficulty - client.difficulty;
|
||||
}
|
||||
else if (avg < tMin){
|
||||
if (ddiff < 1)
|
||||
ddiff = 1;
|
||||
var diffMax = networkDifficulty < options.maxDifficulty ? networkDifficulty : options.maxDifficulty;
|
||||
if (ddiff + client.difficulty > diffMax)
|
||||
ddiff = diffMax - client.difficulty;
|
||||
}
|
||||
else{
|
||||
console.log('hashrate in range ' + JSON.stringify({ddiff: ddiff, avg: avg}) );
|
||||
return;
|
||||
}
|
||||
|
||||
var newDiff = client.difficulty * ddiff;
|
||||
timeBuffer.clear();
|
||||
|
||||
console.log('sending new difficutly ' + newDiff);
|
||||
|
||||
client.sendDifficulty(newDiff);
|
||||
});
|
||||
};
|
||||
};
|
||||
varDiff.prototype.__proto__ = events.EventEmitter.prototype;
|
||||
Loading…
Reference in New Issue
Block a user