This commit is contained in:
Matthew Little 2014-01-07 01:29:03 -05:00
parent 2e02a3f44b
commit b37f4f974b
7 changed files with 56 additions and 33 deletions

View File

@ -17,6 +17,9 @@ Features (mostly untested)
* Handle share submissions * Handle share submissions
* Payment processing module * Payment processing module
* Support more algos (scrypt, scrypt-jane, quark) * 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 * Statistics module
* Integrate with PostgreSQL database * Integrate with PostgreSQL database
* Web frontend * Web frontend

View File

@ -6,7 +6,7 @@ var transactions = require('./transactions.js');
var util = require('./util.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 //private members
@ -33,7 +33,8 @@ var BlockTemplate = module.exports = function BlockTemplate(jobId, rpcData, publ
this.generationTransaction = new transactions.Generation( this.generationTransaction = new transactions.Generation(
rpcData, rpcData,
publicKey, publicKey,
reward reward,
extraNoncePlaceholder
); );
this.getJobParams = function(){ this.getJobParams = function(){

View File

@ -1,26 +1,18 @@
var events = require('events'); var events = require('events');
var binpack = require('binpack'); var binpack = require('binpack');
var bignum = require('bignum');
var transactions = require('./transactions.js');
var util = require('./util.js'); var util = require('./util.js');
var blockTemplate = require('./blockTemplate.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 //Unique extranonce per subscriber
var ExtraNonceCounter = function(){ var ExtraNonceCounter = function(){
var instanceId = 31; var instanceId = 31;
var counter = instanceId << 27; var counter = instanceId << 27;
var size = 4; var size = binpack.packUInt32(counter, 'big').length;
this.next = function(){ this.next = function(){
var extraNonce = binpack.packUInt32(counter++, 'big'); var extraNonce = binpack.packUInt32(counter++, 'big');
@ -66,11 +58,21 @@ var JobManager = module.exports = function JobManager(options){
//public members //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.currentJob; this.currentJob;
this.newTemplate = function(rpcData, publicKey){ 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; jobs[this.currentJob.jobId] = this.currentJob;
CheckNewIfNewBlock(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; JobManager.prototype.__proto__ = events.EventEmitter.prototype;

View File

@ -11,7 +11,7 @@ var coins = [
new Coin({ new Coin({
name: 'Dogecoin', name: 'Dogecoin',
symbol: 'doge', symbol: 'doge',
algorithm: 'scrypt', algorithm: 'scrypt', //or sha256, scrypt-jane, quark
reward: 'POW', //or POS reward: 'POW', //or POS
address: 'D5uXR7F6bTCJKRZBqj1D4gyHF9MHAd5oNs', address: 'D5uXR7F6bTCJKRZBqj1D4gyHF9MHAd5oNs',
stratumPort: 3333, stratumPort: 3333,
@ -26,7 +26,6 @@ var coins = [
}) })
]; ];
coins.forEach(function(coin){ coins.forEach(function(coin){
coin.pool = new pool(coin); coin.pool = new pool(coin);
@ -35,7 +34,6 @@ coins.forEach(function(coin){
var blockNotifyServer = net.createServer(function(c) { var blockNotifyServer = net.createServer(function(c) {
console.log('server connected'); console.log('server connected');
var data = ''; var data = '';

15
pool.js
View File

@ -1,14 +1,12 @@
var net = require('net'); var net = require('net');
var events = require('events'); var events = require('events');
var bignum = require('bignum');
var async = require('async'); var async = require('async');
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');
var util = require('./util.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){ this.stratumServer.on('client', function(client){
client.on('subscription', function(params, result){ client.on('subscription', function(params, result){
var extraNonce = _this.jobManager.extraNonceCounter.next(); var extraNonce = _this.jobManager.extraNonceCounter.next();
var extraNonce2Size = transactions.extranonce_size - _this.jobManager.extraNonceCounter.size(); var extraNonce2Size = _this.jobManager.extraNonce2Size;
result(extraNonce, extraNonce2Size); result(extraNonce, extraNonce2Size);
this.sendDifficulty(1); this.sendDifficulty(1);
this.sendMiningJob(_this.jobManager.currentJob.getJobParams()); this.sendMiningJob(_this.jobManager.currentJob.getJobParams());
}).on('authorize', function(params, result){ }).on('authorize', function(params, result){
result(true); result(true);
}).on('submit', function(params, result){ }).on('submit', function(params, result){
var accepted =_this.jobManager.processShare(
result(true); result.jobId,
client.difficulty,
client.extraNonce1,
result.extraNonce2,
result.nTime,
result.nonce
);
result(accepted);
}); });
}); });
}; };

View File

@ -49,7 +49,7 @@ var StratumClient = function(options){
_this.emit('subscription', _this.emit('subscription',
{}, {},
function(extraNonce1, extraNonce2Size){ function(extraNonce1, extraNonce2Size){
_this.extraNonce = extraNonce1; _this.extraNonce1 = extraNonce1;
sendJson({ sendJson({
id: message.id, id: message.id,
result: [ result: [
@ -70,6 +70,7 @@ var StratumClient = function(options){
password: message.params[0][1] password: message.params[0][1]
}, },
function(authorized){ function(authorized){
_this.authorized = authorized;
sendJson({ sendJson({
id: message.id, id: message.id,
result: authorized, result: authorized,
@ -80,6 +81,22 @@ var StratumClient = function(options){
} }
function handleSubmit(message){ 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', _this.emit('submit',
{ {
name: message.params[0], name: message.params[0],
@ -144,6 +161,7 @@ var StratumClient = function(options){
//public members //public members
this.sendDifficulty = function(difficulty){ this.sendDifficulty = function(difficulty){
_this.difficulty = difficulty;
sendJson({ sendJson({
id: null, id: null,
method: "mining.set_difficulty", method: "mining.set_difficulty",

View File

@ -4,10 +4,6 @@ var buffertools = require('buffertools');
var util = require('./util.js'); var util = require('./util.js');
var extranonce_placeholder = new Buffer('f000000ff111111f', 'hex');
exports.extranonce_size = extranonce_placeholder.length;
function Transaction(params){ function Transaction(params){
var version; var version;
var inputs; var inputs;
@ -107,20 +103,20 @@ function TransactionOutput(params){
}; };
} }
var buildScriptSig = function(height, flags){ var buildScriptSig = function(height, flags, extraNoncePlaceholder){
return Buffer.concat([ return Buffer.concat([
util.serializeNumber(height), util.serializeNumber(height),
new Buffer(flags, 'hex'), new Buffer(flags, 'hex'),
util.serializeNumber(Date.now() / 1000 | 0), util.serializeNumber(Date.now() / 1000 | 0),
new Buffer([exports.extranonce_size]), new Buffer([extraNoncePlaceholder.length]),
extranonce_placeholder, extraNoncePlaceholder,
util.serializeString('/nodeStratum/') 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({ var tx = new Transaction({
inputs: [new TransactionInput({ inputs: [new TransactionInput({
@ -134,9 +130,9 @@ var Generation = exports.Generation = function Generation(rpcData, publicKey){
}); });
var txBuffer = tx.toBuffer(); var txBuffer = tx.toBuffer();
var epIndex = buffertools.indexOf(txBuffer, extranonce_placeholder); var epIndex = buffertools.indexOf(txBuffer, extraNoncePlaceholder);
var p1 = txBuffer.slice(0, epIndex); 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.transaction = tx;
this.coinbase = [p1, p2]; this.coinbase = [p1, p2];