updated
This commit is contained in:
parent
2e02a3f44b
commit
b37f4f974b
@ -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
|
||||||
|
|||||||
@ -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(){
|
||||||
|
|||||||
@ -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;
|
||||||
4
main.js
4
main.js
@ -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
15
pool.js
@ -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);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
20
stratum.js
20
stratum.js
@ -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",
|
||||||
|
|||||||
@ -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];
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user