diff --git a/README.md b/README.md index b58be19..74d812e 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,9 @@ Features (mostly untested) * Handle share submissions * Payment processing module * Support more algos (scrypt, scrypt-jane, quark) + * Port [scrypt hash](https://github.com/Tydus/litecoin_scrypt) to node module + * Port [scrypt-jane hash](https://github.com/Rav3nPL/p2pool-yac/tree/master/yac_scrypt) to node module + * Port [quark hash](https://github.com/Neisklar/quarkcoin-hash-python) to node module * Statistics module * Integrate with PostgreSQL database * Web frontend diff --git a/blockTemplate.js b/blockTemplate.js index 9702ba3..b476c73 100644 --- a/blockTemplate.js +++ b/blockTemplate.js @@ -6,7 +6,7 @@ var transactions = require('./transactions.js'); var util = require('./util.js'); -var BlockTemplate = module.exports = function BlockTemplate(jobId, rpcData, publicKey, reward){ +var BlockTemplate = module.exports = function BlockTemplate(jobId, rpcData, publicKey, reward, extraNoncePlaceholder){ //private members @@ -33,7 +33,8 @@ var BlockTemplate = module.exports = function BlockTemplate(jobId, rpcData, publ this.generationTransaction = new transactions.Generation( rpcData, publicKey, - reward + reward, + extraNoncePlaceholder ); this.getJobParams = function(){ diff --git a/jobManager.js b/jobManager.js index 31c316b..2095a6a 100644 --- a/jobManager.js +++ b/jobManager.js @@ -1,26 +1,18 @@ var events = require('events'); var binpack = require('binpack'); +var bignum = require('bignum'); -var transactions = require('./transactions.js'); var util = require('./util.js'); var blockTemplate = require('./blockTemplate.js'); -/* - -For each crypto currency have a templating instance which holds an array of jobs. -jobs all hold slightly modified block templates that all have the same prev hash. -any jobs with outdated prevhash should be purged. - - - */ //Unique extranonce per subscriber var ExtraNonceCounter = function(){ var instanceId = 31; var counter = instanceId << 27; - var size = 4; + var size = binpack.packUInt32(counter, 'big').length; this.next = function(){ var extraNonce = binpack.packUInt32(counter++, 'big'); @@ -66,11 +58,21 @@ var JobManager = module.exports = function JobManager(options){ //public members this.extraNonceCounter = new ExtraNonceCounter(); + this.extraNoncePlaceholder = new Buffer('f000000ff111111f', 'hex'); + this.extraNonce2Size = this.extraNoncePlaceholder.length - this.extraNonceCounter.size(); + this.currentJob; this.newTemplate = function(rpcData, publicKey){ - this.currentJob = new blockTemplate(jobCounter.next(), rpcData, publicKey); + this.currentJob = new blockTemplate(jobCounter.next(), rpcData, publicKey, _this.extraNoncePlaceholder); jobs[this.currentJob.jobId] = this.currentJob; CheckNewIfNewBlock(this.currentJob); }; + this.processShare = function(jobId, difficulty, extraNonce1, extraNonce2, nTime, nonce){ + + var submitTime = Date.now() / 1000 | 0; + + + return true; + }; }; JobManager.prototype.__proto__ = events.EventEmitter.prototype; \ No newline at end of file diff --git a/main.js b/main.js index 7f62a0b..d8619f8 100644 --- a/main.js +++ b/main.js @@ -11,7 +11,7 @@ var coins = [ new Coin({ name: 'Dogecoin', symbol: 'doge', - algorithm: 'scrypt', + algorithm: 'scrypt', //or sha256, scrypt-jane, quark reward: 'POW', //or POS address: 'D5uXR7F6bTCJKRZBqj1D4gyHF9MHAd5oNs', stratumPort: 3333, @@ -26,7 +26,6 @@ var coins = [ }) ]; - coins.forEach(function(coin){ coin.pool = new pool(coin); @@ -35,7 +34,6 @@ coins.forEach(function(coin){ - var blockNotifyServer = net.createServer(function(c) { console.log('server connected'); var data = ''; diff --git a/pool.js b/pool.js index 0b9e438..02f600e 100644 --- a/pool.js +++ b/pool.js @@ -1,14 +1,12 @@ var net = require('net'); var events = require('events'); -var bignum = require('bignum'); var async = require('async'); var daemon = require('./daemon.js'); var stratum = require('./stratum.js'); var jobManager = require('./jobManager.js'); var util = require('./util.js'); -var transactions = require('./transactions.js'); @@ -85,15 +83,22 @@ var pool = module.exports = function pool(coin){ this.stratumServer.on('client', function(client){ client.on('subscription', function(params, result){ var extraNonce = _this.jobManager.extraNonceCounter.next(); - var extraNonce2Size = transactions.extranonce_size - _this.jobManager.extraNonceCounter.size(); + var extraNonce2Size = _this.jobManager.extraNonce2Size; result(extraNonce, extraNonce2Size); this.sendDifficulty(1); this.sendMiningJob(_this.jobManager.currentJob.getJobParams()); }).on('authorize', function(params, result){ result(true); }).on('submit', function(params, result){ - - result(true); + var accepted =_this.jobManager.processShare( + result.jobId, + client.difficulty, + client.extraNonce1, + result.extraNonce2, + result.nTime, + result.nonce + ); + result(accepted); }); }); }; diff --git a/stratum.js b/stratum.js index de8fb94..98fc039 100644 --- a/stratum.js +++ b/stratum.js @@ -49,7 +49,7 @@ var StratumClient = function(options){ _this.emit('subscription', {}, function(extraNonce1, extraNonce2Size){ - _this.extraNonce = extraNonce1; + _this.extraNonce1 = extraNonce1; sendJson({ id: message.id, result: [ @@ -70,6 +70,7 @@ var StratumClient = function(options){ password: message.params[0][1] }, function(authorized){ + _this.authorized = authorized; sendJson({ id: message.id, result: authorized, @@ -80,6 +81,22 @@ var StratumClient = function(options){ } function handleSubmit(message){ + if (!_this.authorized){ + sendJson({ + id: message.id, + result: null, + error: [24, "unauthorized worker", null] + }); + return; + } + if (!_this.extraNonce1){ + sendJson({ + id: message.id, + result: null, + error: [25, "not subscribed", null] + }); + return; + } _this.emit('submit', { name: message.params[0], @@ -144,6 +161,7 @@ var StratumClient = function(options){ //public members this.sendDifficulty = function(difficulty){ + _this.difficulty = difficulty; sendJson({ id: null, method: "mining.set_difficulty", diff --git a/transactions.js b/transactions.js index 96feefc..fbbb5d0 100644 --- a/transactions.js +++ b/transactions.js @@ -4,10 +4,6 @@ var buffertools = require('buffertools'); var util = require('./util.js'); -var extranonce_placeholder = new Buffer('f000000ff111111f', 'hex'); -exports.extranonce_size = extranonce_placeholder.length; - - function Transaction(params){ var version; var inputs; @@ -107,20 +103,20 @@ function TransactionOutput(params){ }; } -var buildScriptSig = function(height, flags){ +var buildScriptSig = function(height, flags, extraNoncePlaceholder){ return Buffer.concat([ util.serializeNumber(height), new Buffer(flags, 'hex'), util.serializeNumber(Date.now() / 1000 | 0), - new Buffer([exports.extranonce_size]), - extranonce_placeholder, + new Buffer([extraNoncePlaceholder.length]), + extraNoncePlaceholder, util.serializeString('/nodeStratum/') ]); }; -var Generation = exports.Generation = function Generation(rpcData, publicKey){ +var Generation = exports.Generation = function Generation(rpcData, publicKey, extraNoncePlaceholder){ - var scriptSig = buildScriptSig(rpcData.height, rpcData.coinbaseaux.flags); + var scriptSig = buildScriptSig(rpcData.height, rpcData.coinbaseaux.flags, extraNoncePlaceholder); var tx = new Transaction({ inputs: [new TransactionInput({ @@ -134,9 +130,9 @@ var Generation = exports.Generation = function Generation(rpcData, publicKey){ }); var txBuffer = tx.toBuffer(); - var epIndex = buffertools.indexOf(txBuffer, extranonce_placeholder); + var epIndex = buffertools.indexOf(txBuffer, extraNoncePlaceholder); var p1 = txBuffer.slice(0, epIndex); - var p2 = txBuffer.slice(epIndex + extranonce_placeholder.length); + var p2 = txBuffer.slice(epIndex + extraNoncePlaceholder.length); this.transaction = tx; this.coinbase = [p1, p2];