bbqpool-stratum
Version:
High performance Stratum poolserver in Node.js. Optimized to build with GCC 10 and O3 / bugfixes
94 lines (75 loc) • 3.04 kB
JavaScript
/*
*
* Difficulty (Update)
*
*/
const events = require('events');
const utils = require('./utils');
////////////////////////////////////////////////////////////////////////////////
// Main Difficulty Function
const Difficulty = function(port, difficulty) {
const _this = this;
_this.options = difficulty;
// Cleanup diff
this.configured = function(client) {
client.lastTs = 0;
client.cb.clear();
}
// Update Difficulty on Share Submission
this.updateDifficulty = function(client) {
const ts = (Date.now() / 1000) | 0;
// We just getting started bois
if (!client.lastTs) {
client.cb.clear();
client.lastTs = ts;
client.optimalDifficulty = _this.options.initial;
return;
}
// Bail-out early if we're still waiting on difficulty update
if(client.optimalDifficulty != client.difficulty) {
client.lastTs = ts;
return;
}
// Update last recorded share timestamp
client.cb.push(ts - client.lastTs);
client.lastTs = ts;
// Keep sampling baby
if(client.cb.count < client.cb.length) {
return;
}
const coef = _this.options.targetTime / (client.cb.toArray().reduce((a,b) => a + b, 0) / client.cb.count);
// Bail-out if we're good
if((coef < (1 + _this.options.variance)) && (coef > (1 - _this.options.variance))) {
return;
}
// We're out of "the zone", let's try to fix that
// That "should"(tm) be the right new difficulty
client.optimalDifficulty = utils.toFixed(client.difficulty * coef, 8);
// Make sure we don't swing to hard after the initial correction
if(client.optimalDifficulty > (client.difficulty * (1 + _this.options.variance)) && client.difficulty != _this.options.initial) {
client.optimalDifficulty = utils.toFixed(client.difficulty * (1 + _this.options.variance), 8);
} else if(client.optimalDifficulty < (client.difficulty * (1 - _this.options.variance)) && client.difficulty != _this.options.initial) {
client.optimalDifficulty = utils.toFixed(client.difficulty * (1 - _this.options.variance), 8);
}
// Ensure we don't go higher than legal maximum and minimum
if(client.optimalDifficulty > _this.options.maximum) {
client.optimalDifficulty = _this.options.maximum;
} else if(client.optimalDifficulty < _this.options.minimum) {
client.optimalDifficulty = _this.options.minimum;
}
// Reset buffers then emit new optimal difficulty
client.cb.clear();
_this.emit('newDifficulty', client, client.optimalDifficulty);
};
// Manage Individual Clients
this.manageClient = function(client) {
const stratumPort = client.socket.localPort;
if (stratumPort != port) {
console.error('Handling a client which is not of this vardiff?');
}
client.on('submit', () => _this.updateDifficulty(client));
client.on('configured', () => _this.configure(client));
};
};
module.exports = Difficulty;
Difficulty.prototype.__proto__ = events.EventEmitter.prototype;