Refactored configuration options to preparation for portal software
This commit is contained in:
parent
b33d5f7941
commit
c81d9c463a
47
README.md
47
README.md
@ -41,7 +41,6 @@ Features
|
|||||||
|
|
||||||
|
|
||||||
#### Under development
|
#### Under development
|
||||||
* Scrypt-VRT (Vertcoin) algorithm
|
|
||||||
* Skein (Skeincoin) algorithm
|
* Skein (Skeincoin) algorithm
|
||||||
* Max (Maxcoin) algorithm
|
* Max (Maxcoin) algorithm
|
||||||
* P2P functionality for highly efficient block updates from daemon as a peer node
|
* P2P functionality for highly efficient block updates from daemon as a peer node
|
||||||
@ -92,21 +91,26 @@ Create and start new pool with configuration options and authentication function
|
|||||||
```javascript
|
```javascript
|
||||||
var pool = stratum.createPool({
|
var pool = stratum.createPool({
|
||||||
|
|
||||||
name: "Dogecoin",
|
coin: {
|
||||||
symbol: "doge",
|
name: "Dogecoin",
|
||||||
algorithm: "scrypt", //or "sha256", "scrypt-jane", "quark", "x11"
|
symbol: "doge",
|
||||||
reward: "POW", //or "POS"
|
algorithm: "scrypt", //or "sha256", "scrypt-jane", "quark", "x11"
|
||||||
txMessages: false //or true
|
reward: "POW", //or "POS"
|
||||||
address: "nhfNedMmQ1Rjb62znwaiJgFhL3f4NQztSp",
|
txMessages: false //or true
|
||||||
stratumPort: 3334,
|
},
|
||||||
//instanceId: 37, //I recommend not to use this option as a crypto-random one will be generated
|
|
||||||
difficulty: 32,
|
pool: {
|
||||||
blockRefreshInterval: 2000, //milliseconds
|
address: "nhfNedMmQ1Rjb62znwaiJgFhL3f4NQztSp",
|
||||||
|
stratumPort: 3334,
|
||||||
|
//instanceId: 37, //I recommend not to use this option as a crypto-random one will be generated
|
||||||
|
difficulty: 32,
|
||||||
|
blockRefreshInterval: 2000 //milliseconds
|
||||||
|
},
|
||||||
|
|
||||||
/* Recommended to have at least two daemon instances running in case one drops out-of-sync
|
/* Recommended to have at least two daemon instances running in case one drops out-of-sync
|
||||||
or offline. For redundancy, all instances will be polled for block/transaction updates
|
or offline. For redundancy, all instances will be polled for block/transaction updates
|
||||||
and be used for submitting blocks */
|
and be used for submitting blocks */
|
||||||
daemon: [
|
daemons: [
|
||||||
{ //main daemon instance
|
{ //main daemon instance
|
||||||
host: "localhost",
|
host: "localhost",
|
||||||
port: 19334,
|
port: 19334,
|
||||||
@ -135,6 +139,25 @@ var pool = stratum.createPool({
|
|||||||
will almost immediately apply new difficulties. Set mode to fast for difficulty
|
will almost immediately apply new difficulties. Set mode to fast for difficulty
|
||||||
to be sent immediately. */
|
to be sent immediately. */
|
||||||
//mode: 'fast'
|
//mode: 'fast'
|
||||||
|
},
|
||||||
|
|
||||||
|
p2p: {
|
||||||
|
enabled: false,
|
||||||
|
host: "localhost",
|
||||||
|
port: 19333,
|
||||||
|
|
||||||
|
/* Found in src as the PROTOCOL_VERSION variable, for example:
|
||||||
|
https://github.com/litecoin-project/litecoin/blob/85f303d883ffff35238eaea5174b780c950c0ae4/src/version.h#L28
|
||||||
|
*/
|
||||||
|
protocolVersion: 70002,
|
||||||
|
|
||||||
|
/* Magic value is different for main/testnet and for each coin. It is found in the daemon
|
||||||
|
source code as the pchMessageStart variable. For example, litecoin mainnet:
|
||||||
|
http://github.com/litecoin-project/litecoin/blob/85f303d883ffff35238eaea5174b780c950c0ae4/src/main.cpp#L3059
|
||||||
|
And for litecoin testnet:
|
||||||
|
http://github.com/litecoin-project/litecoin/blob/85f303d883ffff35238eaea5174b780c950c0ae4/src/main.cpp#L2722-L2725
|
||||||
|
*/
|
||||||
|
magic: "fcc1b7dc"
|
||||||
}
|
}
|
||||||
|
|
||||||
}, function(ip, workerName, password, callback){ //stratum authorization function
|
}, function(ip, workerName, password, callback){ //stratum authorization function
|
||||||
|
|||||||
@ -38,7 +38,7 @@ var index = module.exports = function index(options){
|
|||||||
if (message.password === options.blockNotifyListener.password){
|
if (message.password === options.blockNotifyListener.password){
|
||||||
|
|
||||||
for (var i = 0; i < this.pools.length; i++){
|
for (var i = 0; i < this.pools.length; i++){
|
||||||
if (this.pools[i].options.symbol === message.coin){
|
if (this.pools[i].options.coin.symbol === message.coin){
|
||||||
this.pools[i].processBlockNotify(message.blockHash)
|
this.pools[i].processBlockNotify(message.blockHash)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,6 @@ var quark = require('quark-hash');
|
|||||||
var scryptJane = require('scrypt-jane-hash');
|
var scryptJane = require('scrypt-jane-hash');
|
||||||
var x11 = require('x11-hash');
|
var x11 = require('x11-hash');
|
||||||
|
|
||||||
|
|
||||||
var util = require('./util.js');
|
var util = require('./util.js');
|
||||||
var blockTemplate = require('./blockTemplate.js');
|
var blockTemplate = require('./blockTemplate.js');
|
||||||
|
|
||||||
@ -65,7 +64,6 @@ var JobManager = module.exports = function JobManager(options){
|
|||||||
return '00000000ffff0000000000000000000000000000000000000000000000000000';
|
return '00000000ffff0000000000000000000000000000000000000000000000000000';
|
||||||
case 'scrypt':
|
case 'scrypt':
|
||||||
case 'scrypt-jane':
|
case 'scrypt-jane':
|
||||||
case 'script-vrt':
|
|
||||||
return '0000ffff00000000000000000000000000000000000000000000000000000000';
|
return '0000ffff00000000000000000000000000000000000000000000000000000000';
|
||||||
case 'quark':
|
case 'quark':
|
||||||
case 'x11':
|
case 'x11':
|
||||||
@ -91,10 +89,6 @@ var JobManager = module.exports = function JobManager(options){
|
|||||||
return function(){
|
return function(){
|
||||||
return scryptJane.digest.apply(this, arguments);
|
return scryptJane.digest.apply(this, arguments);
|
||||||
}
|
}
|
||||||
case 'scrypt-vrt':
|
|
||||||
return function(){
|
|
||||||
//https://github.com/scr34m/vertcoin_scrypt
|
|
||||||
}
|
|
||||||
case 'quark':
|
case 'quark':
|
||||||
return function(){
|
return function(){
|
||||||
return quark.digest.apply(this, arguments);
|
return quark.digest.apply(this, arguments);
|
||||||
@ -103,17 +97,28 @@ var JobManager = module.exports = function JobManager(options){
|
|||||||
return function(){
|
return function(){
|
||||||
return x11.digest.apply(this, arguments);
|
return x11.digest.apply(this, arguments);
|
||||||
}
|
}
|
||||||
|
case 'skein':
|
||||||
|
return function(data){
|
||||||
|
|
||||||
|
/*var dataString = data.slice(0, 80).toString('ascii');
|
||||||
|
var skeinHashed = skein(dataString);
|
||||||
|
|
||||||
|
var hash1 = crypto.createHash('sha256');
|
||||||
|
hash1.update(new Buffer(skeinHashed, 'hex'));
|
||||||
|
hash1 = hash1.digest();
|
||||||
|
|
||||||
|
return hash1;*/
|
||||||
|
|
||||||
|
//https://github.com/cruzrr/insanehash
|
||||||
|
//https://github.com/Crypto-Expert/stratum-mining/blob/master/lib/skein.py
|
||||||
|
}
|
||||||
case 'max':
|
case 'max':
|
||||||
return function(){
|
return function(){
|
||||||
|
//Keccak hash
|
||||||
//https://github.com/phusion/node-sha3
|
//https://github.com/phusion/node-sha3
|
||||||
//https://github.com/Prydie/maxcoin-hash-python
|
//https://github.com/Prydie/maxcoin-hash-python
|
||||||
//https://github.com/ahmedbodi/stratum-mining-maxcoin/blob/master/lib/template_registry.py
|
//https://github.com/ahmedbodi/stratum-mining-maxcoin/blob/master/lib/template_registry.py
|
||||||
}
|
}
|
||||||
case 'skein':
|
|
||||||
return function(){
|
|
||||||
//https://github.com/cruzrr/insanehash
|
|
||||||
//https://github.com/Crypto-Expert/stratum-mining/blob/master/lib/skein.py
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|||||||
41
lib/pool.js
41
lib/pool.js
@ -36,7 +36,7 @@ var pool = module.exports = function pool(options, authorizeFn){
|
|||||||
var emitErrorLog = function(key, text) { _this.emit('log', 'error' , key, text); };
|
var emitErrorLog = function(key, text) { _this.emit('log', 'error' , key, text); };
|
||||||
|
|
||||||
this.start = function(){
|
this.start = function(){
|
||||||
emitLog('system', 'Starting pool for ' + options.name + ' [' + options.symbol.toUpperCase() + ']');
|
emitLog('system', 'Starting pool for ' + options.coin.name + ' [' + options.coin.symbol.toUpperCase() + ']');
|
||||||
SetupJobManager();
|
SetupJobManager();
|
||||||
SetupVarDiff();
|
SetupVarDiff();
|
||||||
SetupDaemonInterface();
|
SetupDaemonInterface();
|
||||||
@ -64,7 +64,7 @@ var pool = module.exports = function pool(options, authorizeFn){
|
|||||||
emitLog('system', 'VarDiff has been disabled');
|
emitLog('system', 'VarDiff has been disabled');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_this.varDiff = new varDiff(options.varDiff, options.difficulty);
|
_this.varDiff = new varDiff(options.varDiff, options.pool.difficulty);
|
||||||
_this.varDiff.on('newDifficulty', function(client, newDiff) {
|
_this.varDiff.on('newDifficulty', function(client, newDiff) {
|
||||||
|
|
||||||
if (options.varDiff.mode === 'fast'){
|
if (options.varDiff.mode === 'fast'){
|
||||||
@ -124,10 +124,10 @@ var pool = module.exports = function pool(options, authorizeFn){
|
|||||||
|
|
||||||
function SetupJobManager(){
|
function SetupJobManager(){
|
||||||
_this.jobManager = new jobManager({
|
_this.jobManager = new jobManager({
|
||||||
algorithm : options.algorithm,
|
algorithm : options.coin.algorithm,
|
||||||
address : options.address,
|
address : options.pool.address,
|
||||||
reward : options.reward,
|
reward : options.coin.reward,
|
||||||
txMessages: options.txMessages
|
txMessages: options.coin.txMessages
|
||||||
});
|
});
|
||||||
_this.jobManager.on('newBlock', function(blockTemplate){
|
_this.jobManager.on('newBlock', function(blockTemplate){
|
||||||
//Check if stratumServer has been initialized yet
|
//Check if stratumServer has been initialized yet
|
||||||
@ -173,11 +173,11 @@ var pool = module.exports = function pool(options, authorizeFn){
|
|||||||
|
|
||||||
function SetupDaemonInterface(){
|
function SetupDaemonInterface(){
|
||||||
emitLog('system', 'Connecting to daemon(s)');
|
emitLog('system', 'Connecting to daemon(s)');
|
||||||
_this.daemon = new daemon.interface(options.daemon);
|
_this.daemon = new daemon.interface(options.daemons);
|
||||||
_this.daemon.once('online', function(){
|
_this.daemon.once('online', function(){
|
||||||
async.parallel({
|
async.parallel({
|
||||||
addressInfo: function(callback){
|
addressInfo: function(callback){
|
||||||
_this.daemon.cmd('validateaddress', [options.address], function(results){
|
_this.daemon.cmd('validateaddress', [options.pool.address], function(results){
|
||||||
|
|
||||||
//Make sure address is valid with each daemon
|
//Make sure address is valid with each daemon
|
||||||
var allValid = results.every(function(result){
|
var allValid = results.every(function(result){
|
||||||
@ -282,25 +282,25 @@ var pool = module.exports = function pool(options, authorizeFn){
|
|||||||
|
|
||||||
options.hasSubmitMethod = results.submitMethod;
|
options.hasSubmitMethod = results.submitMethod;
|
||||||
|
|
||||||
if (options.reward === 'POS' && typeof(results.addressInfo.pubkey) == 'undefined') {
|
if (options.coin.reward === 'POS' && typeof(results.addressInfo.pubkey) == 'undefined') {
|
||||||
// address provided is not of the wallet.
|
// address provided is not of the wallet.
|
||||||
emitErrorLog('system', 'The address provided is not from the daemon wallet.');
|
emitErrorLog('system', 'The address provided is not from the daemon wallet.');
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
publicKeyBuffer = options.reward === 'POW' ?
|
publicKeyBuffer = options.coin.reward === 'POW' ?
|
||||||
util.script_to_address(results.addressInfo.address) :
|
util.script_to_address(results.addressInfo.address) :
|
||||||
util.script_to_pubkey(results.addressInfo.pubkey);
|
util.script_to_pubkey(results.addressInfo.pubkey);
|
||||||
|
|
||||||
if (options.difficulty > results.miningInfo.difficulty && options.difficulty > 16){
|
if (options.pool.difficulty > results.miningInfo.difficulty && options.pool.difficulty > 16){
|
||||||
var newDiff = results.miningInfo.difficulty > 16 ? results.miningInfo.difficulty : 16;
|
var newDiff = results.miningInfo.difficulty > 16 ? results.miningInfo.difficulty : 16;
|
||||||
emitWarningLog('system', 'pool difficulty was set higher than network difficulty of ' + results.miningInfo.difficulty);
|
emitWarningLog('system', 'pool difficulty was set higher than network difficulty of ' + results.miningInfo.difficulty);
|
||||||
emitWarningLog('system', 'lowering pool diff from ' + options.difficulty + ' to ' + newDiff);
|
emitWarningLog('system', 'lowering pool diff from ' + options.pool.difficulty + ' to ' + newDiff);
|
||||||
|
|
||||||
options.difficulty = newDiff
|
options.pool.difficulty = newDiff
|
||||||
|
|
||||||
if (options.varDiff.enabled)
|
if (options.varDiff.enabled)
|
||||||
_this.varDiff.setPoolDifficulty(options.difficulty);
|
_this.varDiff.setPoolDifficulty(options.pool.difficulty);
|
||||||
}
|
}
|
||||||
|
|
||||||
GetBlockTemplate(function(error, result){
|
GetBlockTemplate(function(error, result){
|
||||||
@ -328,13 +328,12 @@ var pool = module.exports = function pool(options, authorizeFn){
|
|||||||
|
|
||||||
|
|
||||||
function StartStratumServer(){
|
function StartStratumServer(){
|
||||||
//emitLog('system', 'Stratum server starting on port ' + options.stratumPort);
|
|
||||||
_this.stratumServer = new stratum.Server({
|
_this.stratumServer = new stratum.Server({
|
||||||
port: options.stratumPort,
|
port: options.pool.stratumPort,
|
||||||
authorizeFn: authorizeFn
|
authorizeFn: authorizeFn
|
||||||
});
|
});
|
||||||
_this.stratumServer.on('started', function(){
|
_this.stratumServer.on('started', function(){
|
||||||
emitLog('system','Stratum server started on port ' + options.stratumPort);
|
emitLog('system','Stratum server started on port ' + options.pool.stratumPort);
|
||||||
_this.emit('started');
|
_this.emit('started');
|
||||||
}).on('client.connected', function(client){
|
}).on('client.connected', function(client){
|
||||||
|
|
||||||
@ -352,7 +351,7 @@ var pool = module.exports = function pool(options, authorizeFn){
|
|||||||
extraNonce2Size
|
extraNonce2Size
|
||||||
);
|
);
|
||||||
|
|
||||||
this.sendDifficulty(options.difficulty);
|
this.sendDifficulty(options.pool.difficulty);
|
||||||
this.sendMiningJob(_this.jobManager.currentJob.getJobParams());
|
this.sendMiningJob(_this.jobManager.currentJob.getJobParams());
|
||||||
|
|
||||||
}).on('submit', function(params, resultCallback){
|
}).on('submit', function(params, resultCallback){
|
||||||
@ -385,12 +384,12 @@ var pool = module.exports = function pool(options, authorizeFn){
|
|||||||
|
|
||||||
function SetupBlockPolling(){
|
function SetupBlockPolling(){
|
||||||
|
|
||||||
if (typeof options.blockRefreshInterval !== "number" || options.blockRefreshInterval <= 0){
|
if (typeof options.pool.blockRefreshInterval !== "number" || options.pool.blockRefreshInterval <= 0){
|
||||||
emitLog('system', 'Block template polling has been disabled');
|
emitLog('system', 'Block template polling has been disabled');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var pollingInterval = options.blockRefreshInterval;
|
var pollingInterval = options.pool.blockRefreshInterval;
|
||||||
|
|
||||||
setInterval(function () {
|
setInterval(function () {
|
||||||
GetBlockTemplate(function(error, result){});
|
GetBlockTemplate(function(error, result){});
|
||||||
@ -443,7 +442,7 @@ var pool = module.exports = function pool(options, authorizeFn){
|
|||||||
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)
|
||||||
emitErrorLog('system', 'Block notify error getting block template for ' + options.name);
|
emitErrorLog('system', 'Block notify error getting block template for ' + options.coin.name);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user