From 61db6d7ea42749d5156d630ef6a03116005ab412 Mon Sep 17 00:00:00 2001 From: Andrea Baccega Date: Tue, 14 Jan 2014 14:32:30 +0100 Subject: [PATCH] Removed jobs object from jobManager since we only need one job! There's no need to keep the olders in memory. Refactored, a bit, the emit log event introducing a key for every log message Current keys are: - 'client': for all the client related events - 'submitblock': dedicated only to events about the block submission! - 'system': all log events about the stratum pool --- TODOLIST.md | 3 +-- lib/daemon.js | 5 ---- lib/jobManager.js | 44 +++++++++++++++++------------------ lib/pool.js | 58 +++++++++++++++++++++++++++-------------------- lib/stratum.js | 13 ++++------- 5 files changed, 61 insertions(+), 62 deletions(-) diff --git a/TODOLIST.md b/TODOLIST.md index 97523d8..f0f5006 100644 --- a/TODOLIST.md +++ b/TODOLIST.md @@ -1,7 +1,6 @@ #### TODO - * vekexasia: handle socket error from client so that we could clean up stratumServers Client - * vekexasia: fix check of difficulty of the shares. Not sure why a lot of shares are marked as "low-submit-share" + #### TOFIX * vekexasia: jobManager.js has implement the expected block hash after submitting it to the daemon. This will let us check if the block was accepted by the daemon. diff --git a/lib/daemon.js b/lib/daemon.js index c98cb30..d652c04 100644 --- a/lib/daemon.js +++ b/lib/daemon.js @@ -61,11 +61,6 @@ function DaemonInterface(options){ params: params }); - if (method == 'submitblock') { - console.log("SUBMITBLOCK daemon"); - console.log(requestJson); - } - var options = { hostname: (typeof(_this.options.host) === 'undefined'?'localhost':_this.options.host), port : _this.options.port, diff --git a/lib/jobManager.js b/lib/jobManager.js index 0eda2be..9b38305 100644 --- a/lib/jobManager.js +++ b/lib/jobManager.js @@ -55,8 +55,6 @@ var JobManager = module.exports = function JobManager(options){ var _this = this; var jobCounter = new JobCounter(); - var jobs = {}; - /** * It only checks if the blockTemplate is already in our jobs list. @@ -64,14 +62,13 @@ var JobManager = module.exports = function JobManager(options){ * used by onNewTemplate **/ function CheckNewIfNewBlock(prevBlockHash){ - - var newBlock = true; - for(var job in jobs){ - if (jobs[job].rpcData.previousblockhash === prevBlockHash) { - newBlock = false; - } + if (typeof(_this.currentJob) === 'undefined') { + return true; + } else if (_this.currentJob.rpcData.previousblockhash !== prevBlockHash) { + return true; + } else { + return false; } - return newBlock; } var diffDividend = (function(){ @@ -128,9 +125,9 @@ var JobManager = module.exports = function JobManager(options){ //public members - this.extraNonceCounter = new ExtraNonceCounter(); + this.extraNonceCounter = new ExtraNonceCounter(); this.extraNoncePlaceholder = new Buffer('f000000ff111111f', 'hex'); - this.extraNonce2Size = this.extraNoncePlaceholder.length - this.extraNonceCounter.size(); + this.extraNonce2Size = this.extraNoncePlaceholder.length - this.extraNonceCounter.size(); this.currentJob; @@ -138,9 +135,11 @@ var JobManager = module.exports = function JobManager(options){ if (CheckNewIfNewBlock(rpcData.previousblockhash)){ var tmpBlockTemplate = new blockTemplate(rpcData, publicKey, _this.extraNoncePlaceholder); tmpBlockTemplate.setJobId(jobCounter.next()); - jobs[tmpBlockTemplate.jobId] = tmpBlockTemplate; - this.currentJob = jobs[tmpBlockTemplate.jobId]; + + this.currentJob = tmpBlockTemplate; + _this.emit('newBlock', tmpBlockTemplate); + } }; @@ -151,8 +150,8 @@ var JobManager = module.exports = function JobManager(options){ if (extraNonce2.length / 2 !== _this.extraNonce2Size) return {error: [20, 'incorrect size of extranonce2', null]}; - var job = jobs[jobId]; - if (!job) { + var job = this.currentJob; + if ( job.jobId != jobId ) { return {error: [21, 'job not found', null]}; } @@ -191,14 +190,13 @@ var JobManager = module.exports = function JobManager(options){ if (job.target.ge(headerBigNum)){ var blockBuf = job.serializeBlock(headerBuffer, coinbaseBuffer); - console.log("EXPECTED BLOCK HASH: "+blockHashHex(headerBuffer)); // NOT WORKING :(? - _this.emit('blockFound', blockBuf.toString('hex')); - } - - // TODO: this seems to not be working properly - var targetUser = bignum(diffDividend / difficulty); - if (headerBigNum.gt(targetUser)){ - return {error: [23, 'low difficulty share', null]}; + // console.log("EXPECTED BLOCK HASH: "+blockHashHex(headerBuffer)); // NOT WORKING :(? + _this.emit('blockFound', blockBuf.toString('hex'), blockHashHex(headerBuffer)); + } else { + var targetUser = bignum(diffDividend / difficulty); + if (headerBigNum.gt(targetUser)){ + return {error: [23, 'low difficulty share', null]}; + } } return {result: true, headerHEX: headerBigNum.toString(16)}; diff --git a/lib/pool.js b/lib/pool.js index 4a91a3f..a691273 100644 --- a/lib/pool.js +++ b/lib/pool.js @@ -19,8 +19,9 @@ var pool = module.exports = function pool(options, authorizeFn){ var publicKeyBuffer; - var emitLog = function(text){ _this.emit('log', text) }; - + var emitLog = function(key, text) { _this.emit('log', 'debug' , key, text); }; + var emitWarningLog = function(key, text) { _this.emit('log', 'warning', key, text); }; + var emitErrorLog = function(key, text) { _this.emit('log', 'error' , key, text); }; (function Init(){ SetupJobManager(); @@ -36,27 +37,24 @@ var pool = module.exports = function pool(options, authorizeFn){ }); _this.jobManager.on('newBlock', function(blockTemplate){ if ( typeof(_this.stratumServer ) === 'undefined') { - console.warn("Stratum server still not started! cannot broadcast block!"); + emitWarningLog("Stratum server still not started! cannot broadcast block!"); } else { + emitLog('system', 'Detected new block'); _this.stratumServer.broadcastMiningJobs(blockTemplate.getJobParams()); } - }).on('blockFound', function(blockHex, headerHex, third){ + }).on('blockFound', function(blockHex, headerHex){ if (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)); + emitLog('submitblock', 'Submitted Block using submitblock :'+headerHex); } ); } 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)); + emitLog('submitblock', 'Submitted Block using getblocktemplate: '+headerHex); } ); } @@ -65,7 +63,7 @@ var pool = module.exports = function pool(options, authorizeFn){ function SetupDaemonInterface(){ - emitLog('Connecting to daemon'); + emitLog('system','Connecting to daemon'); _this.daemon = new daemon.interface(options.daemon); _this.daemon.on('online', function(){ async.parallel({ @@ -74,10 +72,10 @@ var pool = module.exports = function pool(options, authorizeFn){ [options.address], function(error, result){ if (error){ - emitLog('validateaddress rpc error'); + emitLog('system','validateaddress rpc error'); callback(error); } else if (!result.isvalid) { - emitLog('address is not valid'); + emitLog('system','address is not valid'); callback("address-not-valid"); } else { callback(error, result); @@ -99,7 +97,7 @@ var pool = module.exports = function pool(options, authorizeFn){ }, function(err, results){ if (err) return; - emitLog('Connected to daemon'); + emitLog('system','Connected to daemon'); options.hasSubmitMethod = results.submitMethod; publicKeyBuffer = options.reward === 'POW' ? @@ -112,19 +110,19 @@ var pool = module.exports = function pool(options, authorizeFn){ }); }).on('startFailed', function(){ - emitLog('Failed to start daemon'); + emitErrorLog('system','Failed to start daemon'); }); } function StartStratumServer(){ - emitLog('Stratum server starting on port ' + options.stratumPort); + emitLog('system', 'Stratum server starting on port ' + options.stratumPort); _this.stratumServer = new stratum.Server({ port: options.stratumPort, authorizeFn: authorizeFn }); _this.stratumServer.on('started', function(){ - emitLog('Stratum server started on port ' + options.stratumPort); + emitLog('system','Stratum server started on port ' + options.stratumPort); }).on('client.connected', function(client){ client.on('subscription', function(params, resultCallback){ @@ -136,7 +134,11 @@ var pool = module.exports = function pool(options, authorizeFn){ ); this.sendAndSetDifficultyIfNew(options.difficulty); - this.sendMiningJob(_this.jobManager.currentJob.getJobParams()); + if (typeof(_this.jobManager.currentJob) !== 'undefined') { + this.sendMiningJob(_this.jobManager.currentJob.getJobParams()); + } else { + emitWarningLog('client', "A miner subscribed but no job to dispatch!"); + } }).on('submit', function(params, resultCallback){ @@ -166,7 +168,14 @@ var pool = module.exports = function pool(options, authorizeFn){ nonce : params.nonce }); } - + }).on('malformedMessage', function (message) { + emitWarningLog('client', client.workerName+" has sent us a malformed message: "+message); + }).on('socketError', function() { + emitWarningLog('client', client.workerName+" has somehow had a socket error"); + }).on('socketDisconnect', function() { + emitLog('client', "Client '"+client.workerName+"' disconnected!"); + }).on('unknownStratumMethod', function(fullMessage) { + emitLog('client', "Client '"+client.workerName+"' has sent us an unknown stratum method: "+fullMessage.method); }); }); } @@ -174,7 +183,7 @@ var pool = module.exports = function pool(options, authorizeFn){ function SetupBlockPolling(){ if (options.blockRefreshInterval === 0){ - emitLog('Block template polling has been disabled'); + emitLog('system', 'Block template polling has been disabled'); return; } @@ -184,13 +193,14 @@ var pool = module.exports = function pool(options, authorizeFn){ setInterval(function () { GetBlockTemplate(function(error, result) { - if (error) - console.error("Block polling error getting block template for " + options.name); + if (error) { + emitErrorLog('system', "Block polling error getting block template for " + options.name) + } }); }, pollingInterval); - emitLog('Block polling setup for every ' + pollingInterval + ' milliseconds'); + emitLog('system', 'Block polling setup for every ' + pollingInterval + ' milliseconds'); } @@ -217,7 +227,7 @@ var pool = module.exports = function pool(options, authorizeFn){ if (blockHash !== _this.jobManager.currentJob.rpcData.previousblockhash){ GetBlockTemplate(function(error, result){ if (error) - console.error('Block notify error getting block template for ' + options.name); + emitErrorLog('system', 'Block notify error getting block template for ' + options.name); }) } } diff --git a/lib/stratum.js b/lib/stratum.js index 98076e7..97e2c91 100644 --- a/lib/stratum.js +++ b/lib/stratum.js @@ -54,7 +54,7 @@ var StratumClient = function(options){ }); break; default: - console.dir('unknown stratum client message: ' + JSON.stringify(message)); + _this.emit('unknownStratumMethod', message); break; } } @@ -155,19 +155,18 @@ var StratumClient = function(options){ var dataBuffer = ''; socket.setEncoding('utf8'); socket.on('data', function(d){ - console.log('request: ' + d); dataBuffer += d; if (dataBuffer.slice(-1) === '\n'){ var messages = dataBuffer.split('\n'); messages.forEach(function(message){ if (message.trim() === '') return; var messageJson; - try{ + try { messageJson = JSON.parse(message); + } catch(e) { + _this.emit('malformedMessage', message); } - catch(e){ - console.log('could not parse stratum client socket message: ' + message); - } + if (messageJson) { handleMessage(messageJson); } @@ -177,11 +176,9 @@ var StratumClient = function(options){ }); socket.on('end', function() { _this.emit('socketDisconnect') - console.log('stratum client disconnected'); }); socket.on('error', function(){ _this.emit('socketError'); - console.log('stratum client socket error'); }); }