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 events = require('events');
|
||||||
var async = require('async');
|
var async = require('async');
|
||||||
|
|
||||||
|
var varDiff = require('./varDifff.js');
|
||||||
var daemon = require('./daemon.js');
|
var daemon = require('./daemon.js');
|
||||||
var stratum = require('./stratum.js');
|
var stratum = require('./stratum.js');
|
||||||
var jobManager = require('./jobManager.js');
|
var jobManager = require('./jobManager.js');
|
||||||
@ -22,6 +24,7 @@ var util = require('./util.js');
|
|||||||
var pool = module.exports = function pool(options, authorizeFn){
|
var pool = module.exports = function pool(options, authorizeFn){
|
||||||
|
|
||||||
this.options = options;
|
this.options = options;
|
||||||
|
|
||||||
var _this = this;
|
var _this = this;
|
||||||
var publicKeyBuffer;
|
var publicKeyBuffer;
|
||||||
|
|
||||||
@ -32,10 +35,34 @@ var pool = module.exports = function pool(options, authorizeFn){
|
|||||||
|
|
||||||
(function Init(){
|
(function Init(){
|
||||||
SetupJobManager();
|
SetupJobManager();
|
||||||
|
SetupVarDiff();
|
||||||
SetupDaemonInterface();
|
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
|
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 = new daemon.interface(options.daemon);
|
||||||
_this.daemon.on('online', function(){
|
_this.daemon.on('online', function(){
|
||||||
async.parallel({
|
async.parallel({
|
||||||
|
difficulty: RequestDifficulty,
|
||||||
addressInfo: function(callback){
|
addressInfo: function(callback){
|
||||||
_this.daemon.cmd('validateaddress',
|
_this.daemon.cmd('validateaddress',
|
||||||
[options.address],
|
[options.address],
|
||||||
@ -178,6 +206,9 @@ var pool = module.exports = function pool(options, authorizeFn){
|
|||||||
emitLog('system','Stratum server started on port ' + options.stratumPort);
|
emitLog('system','Stratum server started on port ' + options.stratumPort);
|
||||||
_this.emit('started');
|
_this.emit('started');
|
||||||
}).on('client.connected', function(client){
|
}).on('client.connected', function(client){
|
||||||
|
|
||||||
|
_this.varDiff.manageClient(client);
|
||||||
|
|
||||||
client.on('subscription', function(params, resultCallback){
|
client.on('subscription', function(params, resultCallback){
|
||||||
|
|
||||||
var extraNonce = _this.jobManager.extraNonceCounter.next();
|
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