refactored block polling and pool setup
This commit is contained in:
parent
677bc176a4
commit
f8efd80488
@ -3,15 +3,15 @@
|
|||||||
"symbol": "doge",
|
"symbol": "doge",
|
||||||
"algorithm": "scrypt",
|
"algorithm": "scrypt",
|
||||||
"reward": "POW",
|
"reward": "POW",
|
||||||
"address": "mkLyYQ5U8aFQ8aDAF1GS9zXStTzi3m29Tg",
|
"address": "DDt79i6P3Wro3SD3HSnkRLpMgUGUGdiNhS",
|
||||||
"stratumPort": 3334,
|
"stratumPort": 3334,
|
||||||
"difficulty": 8,
|
"difficulty": 8,
|
||||||
"templateRefreshInterval": 60,
|
"blockRefreshInterval": 60,
|
||||||
"merkleRefreshInterval": 60,
|
"merkleRefreshInterval": 60,
|
||||||
"daemon": {
|
"daemon": {
|
||||||
"host": "localhost",
|
"host": "localhost",
|
||||||
"port": 19334,
|
"port": 8332,
|
||||||
"user": "testnet",
|
"user": "test",
|
||||||
"password": "AHhQYqfSZqzQvkSXAtHtDAbKaZaoPih3wfmJfgCtjRx9"
|
"password": "test"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
23
init.js
23
init.js
@ -39,23 +39,6 @@ fs.readdir(confFolder, function(err, files){
|
|||||||
coin.shareManager = new ShareManager(coin.pool);
|
coin.shareManager = new ShareManager(coin.pool);
|
||||||
|
|
||||||
coins.push(coin);
|
coins.push(coin);
|
||||||
|
|
||||||
// If the block notify listener is not enabled lets set up the polling.
|
|
||||||
if ( ! config.blockNotifyListener.enabled ) {
|
|
||||||
// as soon as the pool is started we start polling
|
|
||||||
var pollingTime = typeof(config.blockPollingTime) === 'undefined' ? 5000 : parseInt(config.blockPollingTime, 10);
|
|
||||||
coin.pool.on('started', function() {
|
|
||||||
var curPool = this;
|
|
||||||
setInterval(
|
|
||||||
function() {
|
|
||||||
curPool.processBlockPolling();
|
|
||||||
},
|
|
||||||
pollingTime
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -63,7 +46,7 @@ fs.readdir(confFolder, function(err, files){
|
|||||||
|
|
||||||
|
|
||||||
if (config.blockNotifyListener.enabled){
|
if (config.blockNotifyListener.enabled){
|
||||||
console.log("ENABLED");
|
console.log("Block listener is enabled, starting server on port " + config.blockNotifyListener.port);
|
||||||
var blockNotifyServer = net.createServer(function(c) {
|
var blockNotifyServer = net.createServer(function(c) {
|
||||||
console.log('server connected');
|
console.log('server connected');
|
||||||
var data = '';
|
var data = '';
|
||||||
@ -90,5 +73,7 @@ if (config.blockNotifyListener.enabled){
|
|||||||
console.log('server disconnected');
|
console.log('server disconnected');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
blockNotifyServer.listen(config.blockNotifyListener.port, function() {});
|
blockNotifyServer.listen(config.blockNotifyListener.port, function() {
|
||||||
|
console.log('Block notify listener server started on port ' + config.blockNotifyListener.port)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
@ -59,7 +59,7 @@ var JobManager = module.exports = function JobManager(options){
|
|||||||
* @returns true if it's a new block, false otherwise.
|
* @returns true if it's a new block, false otherwise.
|
||||||
* used by onNewTemplate
|
* used by onNewTemplate
|
||||||
**/
|
**/
|
||||||
function CheckNewIfNewBlock(blockTemplate){
|
function CheckNewIfNewBlock(prevBlockHash){
|
||||||
var newBlock = true;
|
var newBlock = true;
|
||||||
for(var job in jobs){
|
for(var job in jobs){
|
||||||
if (jobs[job].rpcData.previousblockhash === blockTemplate.rpcData.previousblockhash) {
|
if (jobs[job].rpcData.previousblockhash === blockTemplate.rpcData.previousblockhash) {
|
||||||
@ -109,16 +109,17 @@ var JobManager = module.exports = function JobManager(options){
|
|||||||
this.extraNonce2Size = this.extraNoncePlaceholder.length - this.extraNonceCounter.size();
|
this.extraNonce2Size = this.extraNoncePlaceholder.length - this.extraNonceCounter.size();
|
||||||
|
|
||||||
this.currentJob;
|
this.currentJob;
|
||||||
this.newTemplate = function(rpcData, publicKey){
|
|
||||||
var tmpBlockTemplate = new blockTemplate(rpcData, publicKey, _this.extraNoncePlaceholder);
|
this.processTemplate = function(rpcData, publicKey){
|
||||||
if ( CheckNewIfNewBlock(tmpBlockTemplate) ) {
|
if (CheckNewIfNewBlock(rpcData.previousblockhash)){
|
||||||
|
var tmpBlockTemplate = new blockTemplate(rpcData, publicKey, _this.extraNoncePlaceholder);
|
||||||
tmpBlockTemplate.setJobId(jobCounter.next());
|
tmpBlockTemplate.setJobId(jobCounter.next());
|
||||||
jobs[tmpBlockTemplate.jobId] = tmpBlockTemplate;
|
jobs[tmpBlockTemplate.jobId] = tmpBlockTemplate;
|
||||||
this.currentJob = jobs[tmpBlockTemplate.jobId];
|
this.currentJob = jobs[tmpBlockTemplate.jobId];
|
||||||
_this.emit('newBlock', tmpBlockTemplate);
|
_this.emit('newBlock', tmpBlockTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.processShare = function(jobId, difficulty, extraNonce1, extraNonce2, nTime, nonce){
|
this.processShare = function(jobId, difficulty, extraNonce1, extraNonce2, nTime, nonce){
|
||||||
|
|
||||||
var submitTime = Date.now() / 1000 | 0;
|
var submitTime = Date.now() / 1000 | 0;
|
||||||
|
|||||||
216
pool.js
216
pool.js
@ -14,107 +14,109 @@ var pool = module.exports = function pool(coin){
|
|||||||
var _this = this;
|
var _this = this;
|
||||||
var publicKeyBuffer;
|
var publicKeyBuffer;
|
||||||
|
|
||||||
this.shareManager = undefined; // just for us to know that the variable should be this one.
|
(function Init(){
|
||||||
this.jobManager = new jobManager({
|
SetupJobManager();
|
||||||
algorithm: coin.options.algorithm,
|
SetupDaemonInterface();
|
||||||
address: coin.options.address
|
SetupShareManager();
|
||||||
});
|
})();
|
||||||
this.jobManager.on('newBlock', function(blockTemplate){
|
|
||||||
if ( typeof(_this.stratumServer ) === 'undefined') {
|
|
||||||
console.warn("Stratum server still not started! cannot broadcast block!");
|
|
||||||
} else {
|
|
||||||
_this.stratumServer.broadcastMiningJobs(blockTemplate.getJobParams());
|
|
||||||
}
|
|
||||||
|
|
||||||
}).on('blockFound', function(blockHex, headerHex, third){
|
|
||||||
console.log("BLOCK "+blockHex);
|
|
||||||
console.log("HEADER "+headerHex);
|
|
||||||
console.log("THIRD "+third);
|
|
||||||
if (coin.options.hasSubmitMethod) {
|
|
||||||
_this.daemon.cmd('submitblock',
|
|
||||||
[blockHex],
|
|
||||||
function(error, result){
|
|
||||||
console.log(JSON.stringify(error));
|
|
||||||
console.log(JSON.stringify(result));
|
|
||||||
console.log("submitblock", JSON.stringify(error), JSON.stringify(result));
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
_this.daemon.cmd('getblocktemplate',
|
|
||||||
[{'mode': 'submit', 'data': blockHex}],
|
|
||||||
function(error, result){
|
|
||||||
console.log(JSON.stringify(error));
|
|
||||||
console.log(JSON.stringify(result));
|
|
||||||
console.log("submitblockgetBlockTEmplate", JSON.stringify(error), JSON.stringify(result));
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log('Connecting to daemon for ' + coin.options.name);
|
function SetupJobManager(){
|
||||||
this.daemon = new daemon.interface(coin.options.daemon);
|
this.jobManager = new jobManager({
|
||||||
this.daemon.on('online', function(){
|
algorithm: coin.options.algorithm,
|
||||||
async.parallel({
|
address: coin.options.address
|
||||||
rpcTemplate: GetBlockTemplate,
|
});
|
||||||
addressInfo: function(callback){
|
this.jobManager.on('newBlock', function(blockTemplate){
|
||||||
_this.daemon.cmd('validateaddress',
|
if ( typeof(_this.stratumServer ) === 'undefined') {
|
||||||
[coin.options.address],
|
console.warn("Stratum server still not started! cannot broadcast block!");
|
||||||
|
} else {
|
||||||
|
_this.stratumServer.broadcastMiningJobs(blockTemplate.getJobParams());
|
||||||
|
}
|
||||||
|
|
||||||
|
}).on('blockFound', function(blockHex, headerHex, third){
|
||||||
|
if (coin.options.hasSubmitMethod) {
|
||||||
|
_this.daemon.cmd('submitblock',
|
||||||
|
[blockHex],
|
||||||
function(error, result){
|
function(error, result){
|
||||||
if (error){
|
console.log(JSON.stringify(error));
|
||||||
console.log('validateaddress rpc error for ' + coin.options.name);
|
console.log(JSON.stringify(result));
|
||||||
callback(error);
|
console.log("submitblock", JSON.stringify(error), JSON.stringify(result));
|
||||||
}
|
|
||||||
else if (!result.isvalid){
|
|
||||||
console.log('address is not valid for ' + coin.options.name);
|
|
||||||
callback(error);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
callback(error, result);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
} else {
|
||||||
submitMethod: function(callback){
|
_this.daemon.cmd('getblocktemplate',
|
||||||
_this.daemon.cmd('submitblock',
|
[{'mode': 'submit', 'data': blockHex}],
|
||||||
[],
|
|
||||||
function(error, result){
|
function(error, result){
|
||||||
if (error && error.message === 'Method not found')
|
console.log(JSON.stringify(error));
|
||||||
callback(null, false);
|
console.log(JSON.stringify(result));
|
||||||
else
|
console.log("submitblockgetBlockTEmplate", JSON.stringify(error), JSON.stringify(result));
|
||||||
callback(null, true);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}, function(err, results){
|
|
||||||
if (err) return;
|
|
||||||
console.log('Connected to daemon for ' + coin.options.name);
|
|
||||||
coin.options.hasSubmitMethod = results.submitMethod;
|
|
||||||
|
|
||||||
publicKeyBuffer = coin.options.reward === 'POW' ?
|
|
||||||
util.script_to_address(results.addressInfo.address) :
|
|
||||||
util.script_to_pubkey(results.addressInfo.pubkey);
|
|
||||||
|
|
||||||
_this.jobManager.newTemplate(results.rpcTemplate, publicKeyBuffer);
|
|
||||||
|
|
||||||
StartStratumServer();
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}).on('startFailed', function(){
|
|
||||||
console.log('Failed to start daemon for ' + coin.name);
|
function SetupDaemonInterface(){
|
||||||
});
|
console.log('Connecting to daemon for ' + coin.options.name);
|
||||||
|
this.daemon = new daemon.interface(coin.options.daemon);
|
||||||
|
this.daemon.on('online', function(){
|
||||||
|
async.parallel({
|
||||||
|
addressInfo: function(callback){
|
||||||
|
_this.daemon.cmd('validateaddress',
|
||||||
|
[coin.options.address],
|
||||||
|
function(error, result){
|
||||||
|
if (error){
|
||||||
|
console.log('validateaddress rpc error for ' + coin.options.name);
|
||||||
|
callback(error);
|
||||||
|
}
|
||||||
|
else if (!result.isvalid){
|
||||||
|
console.log('address is not valid for ' + coin.options.name);
|
||||||
|
callback(error);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
callback(error, result);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
submitMethod: function(callback){
|
||||||
|
_this.daemon.cmd('submitblock',
|
||||||
|
[],
|
||||||
|
function(error, result){
|
||||||
|
if (error && error.message === 'Method not found')
|
||||||
|
callback(null, false);
|
||||||
|
else
|
||||||
|
callback(null, true);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, function(err, results){
|
||||||
|
if (err) return;
|
||||||
|
console.log('Connected to daemon for ' + coin.options.name);
|
||||||
|
coin.options.hasSubmitMethod = results.submitMethod;
|
||||||
|
|
||||||
|
publicKeyBuffer = coin.options.reward === 'POW' ?
|
||||||
|
util.script_to_address(results.addressInfo.address) :
|
||||||
|
util.script_to_pubkey(results.addressInfo.pubkey);
|
||||||
|
|
||||||
|
StartStratumServer();
|
||||||
|
GetBlockTemplate();
|
||||||
|
SetupBlockPolling();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}).on('startFailed', function(){
|
||||||
|
console.log('Failed to start daemon for ' + coin.name);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function StartStratumServer(){
|
function StartStratumServer(){
|
||||||
|
|
||||||
console.log('Stratum server starting on port ' + coin.options.stratumPort + ' for ' + coin.options.name);
|
console.log('Stratum server starting on port ' + coin.options.stratumPort + ' for ' + coin.options.name);
|
||||||
_this.stratumServer = new stratum.Server({
|
_this.stratumServer = new stratum.Server({
|
||||||
port: coin.options.stratumPort
|
port: coin.options.stratumPort
|
||||||
});
|
});
|
||||||
_this.stratumServer.on('started', function(){
|
_this.stratumServer.on('started', function(){
|
||||||
<<<<<<< HEAD
|
|
||||||
=======
|
|
||||||
_this.emit('started');
|
|
||||||
>>>>>>> a301c49943980d0209fb42114999099eeeb44ded
|
|
||||||
console.log('Stratum server started on port ' + coin.options.stratumPort + ' for ' + coin.options.name);
|
console.log('Stratum server started on port ' + coin.options.stratumPort + ' for ' + coin.options.name);
|
||||||
}).on('client', function(client){
|
}).on('client', function(client){
|
||||||
client.on('subscription', function(params, resultCallback){
|
client.on('subscription', function(params, resultCallback){
|
||||||
@ -165,6 +167,36 @@ var pool = module.exports = function pool(coin){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function SetupShareManager(){
|
||||||
|
this.shareManager = undefined; // just for us to know that the variable should be this one.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function SetupBlockPolling(){
|
||||||
|
|
||||||
|
if (coin.options.blockRefreshInterval === 0){
|
||||||
|
console.log('Block template polling has been disabled for ' + coin.options.name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var pollingInterval = coin.options.blockRefreshInterval * 1000;
|
||||||
|
var pollTimeout;
|
||||||
|
var setPoll;
|
||||||
|
|
||||||
|
setPoll = function(){
|
||||||
|
pollTimeout = setTimeout(function(){
|
||||||
|
GetBlockTemplate(function(error, result) {
|
||||||
|
if (error)
|
||||||
|
console.error("Block polling error getting block template for " + coin.options.name);
|
||||||
|
setPoll();
|
||||||
|
});
|
||||||
|
}, pollingInterval);
|
||||||
|
};
|
||||||
|
console.log('Block polling setup for every ' + pollingInterval + ' milliseconds for ' + coin.options.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function GetBlockTemplate(callback){
|
function GetBlockTemplate(callback){
|
||||||
_this.daemon.cmd('getblocktemplate',
|
_this.daemon.cmd('getblocktemplate',
|
||||||
[{"capabilities": [ "coinbasetxn", "workid", "coinbase/append" ]}],
|
[{"capabilities": [ "coinbasetxn", "workid", "coinbase/append" ]}],
|
||||||
@ -172,24 +204,13 @@ var pool = module.exports = function pool(coin){
|
|||||||
if (error) {
|
if (error) {
|
||||||
callback(error);
|
callback(error);
|
||||||
} else {
|
} else {
|
||||||
|
_this.jobManager.processTemplate(result, publicKeyBuffer);
|
||||||
callback(null, result);
|
callback(null, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This method needs to be called to perform a block polling to the daemon so that we can notify our miners
|
|
||||||
* about new blocks
|
|
||||||
**/
|
|
||||||
this.processBlockPolling = function() {
|
|
||||||
GetBlockTemplate(function(error, result) {
|
|
||||||
if (error) {
|
|
||||||
console.error("[processBlockPolling] Error getting block template for " + coin.options.name);
|
|
||||||
}
|
|
||||||
_this.jobManager.newTemplate(result, publicKeyBuffer);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is being called from the blockNotify so that when a new block is discovered by the daemon
|
* This method is being called from the blockNotify so that when a new block is discovered by the daemon
|
||||||
@ -198,11 +219,8 @@ var pool = module.exports = function pool(coin){
|
|||||||
this.processBlockNotify = function(blockHash){
|
this.processBlockNotify = function(blockHash){
|
||||||
if (blockHash !== _this.jobManager.currentJob.rpcData.previousblockhash){
|
if (blockHash !== _this.jobManager.currentJob.rpcData.previousblockhash){
|
||||||
GetBlockTemplate(function(error, result){
|
GetBlockTemplate(function(error, result){
|
||||||
if (error){
|
if (error)
|
||||||
console.error('[processBlockNotify] Error getting block template for ' + coin.options.name);
|
console.error('Block notify error getting block template for ' + coin.options.name);
|
||||||
return;
|
|
||||||
}
|
|
||||||
_this.jobManager.newTemplate(result, publicKeyBuffer);
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user