Set coin switching feature to not require lower case. Added documentation for proxy and coin switching
This commit is contained in:
parent
36e09e497f
commit
c3ba819f24
71
README.md
71
README.md
@ -133,23 +133,72 @@ Explanation for each field:
|
|||||||
"forks": "auto"
|
"forks": "auto"
|
||||||
},
|
},
|
||||||
|
|
||||||
/* With this enabled, the master process will start listening on the configured port for
|
/* This is the front-end. Its not finished. When it is finished, this comment will say so. */
|
||||||
messages from the 'scripts/blockNotify.js' script which your coin daemons can be configured
|
"website": {
|
||||||
to run when a new block is available. When a blocknotify message is received, the master
|
"enabled": true,
|
||||||
process uses IPC (inter-process communication) to notify each worker process about the
|
"port": 80,
|
||||||
message. Each worker process then sends the message to the appropriate coin pool. See
|
"liveStats": true
|
||||||
"Setting up blocknotify" below to set up your daemon to use this feature. */
|
},
|
||||||
|
|
||||||
|
/* With this enabled, the master process listen on the configured port for messages from the
|
||||||
|
'scripts/blockNotify.js' script which your coin daemons can be configured to run when a
|
||||||
|
new block is available. When a blocknotify message is received, the master process uses
|
||||||
|
IPC (inter-process communication) to notify each thread about the message. Each thread
|
||||||
|
then sends the message to the appropriate coin pool. See "Setting up blocknotify" below to
|
||||||
|
set up your daemon to use this feature. */
|
||||||
"blockNotifyListener": {
|
"blockNotifyListener": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"port": 8117,
|
"port": 8117,
|
||||||
"password": "test"
|
"password": "test"
|
||||||
},
|
},
|
||||||
|
|
||||||
/* This is the front-end. Its not finished. When it is finished, this comment will say so. */
|
/* With this enabled, the master process will listen on the configured port for messages from
|
||||||
"website": {
|
the 'scripts/coinSwitch.js' script which will trigger your proxy pools to switch to the
|
||||||
"enabled": true,
|
specified coin (non-case-sensitive). This setting is used in conjuction with the proxy
|
||||||
"port": 80,
|
feature below. */
|
||||||
"liveStats": true
|
"coinSwitchListener": {
|
||||||
|
"enabled": false,
|
||||||
|
"port": 8118,
|
||||||
|
"password": "test"
|
||||||
|
},
|
||||||
|
|
||||||
|
/* In a proxy configuration, you can setup ports that accept miners for work based on a
|
||||||
|
specific algorithm instead of a specific coin. Miners that connect to these ports are
|
||||||
|
automatically switched a coin determined by the server. The default coin is the first
|
||||||
|
configured pool for each algorithm and coin switching can be triggered using the
|
||||||
|
coinSwitch.js script in the scripts folder.
|
||||||
|
|
||||||
|
Please note miner address authentication must be disabled when using NOMP in a proxy
|
||||||
|
configuration and that payout processing is left up to the server administrator. */
|
||||||
|
"proxy": {
|
||||||
|
"sha256": {
|
||||||
|
"enabled": false,
|
||||||
|
"port": "3333",
|
||||||
|
"diff": 10,
|
||||||
|
"varDiff": {
|
||||||
|
"minDiff": 16, //Minimum difficulty
|
||||||
|
"maxDiff": 512, //Network difficulty will be used if it is lower than this
|
||||||
|
"targetTime": 15, //Try to get 1 share per this many seconds
|
||||||
|
"retargetTime": 90, //Check to see if we should retarget every this many seconds
|
||||||
|
"variancePercent": 30 //Allow time to very this % from target without retargeting
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scrypt": {
|
||||||
|
"enabled": false,
|
||||||
|
"port": "4444",
|
||||||
|
"diff": 10,
|
||||||
|
"varDiff": {
|
||||||
|
"minDiff": 16, //Minimum difficulty
|
||||||
|
"maxDiff": 512, //Network difficulty will be used if it is lower than this
|
||||||
|
"targetTime": 15, //Try to get 1 share per this many seconds
|
||||||
|
"retargetTime": 90, //Check to see if we should retarget every this many seconds
|
||||||
|
"variancePercent": 30 //Allow time to very this % from target without retargeting
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scrypt-n": {
|
||||||
|
"enabled": false,
|
||||||
|
"port": "5555"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
````
|
````
|
||||||
|
|||||||
@ -1,21 +1,11 @@
|
|||||||
{
|
{
|
||||||
"logLevel": "debug",
|
"logLevel": "debug",
|
||||||
|
|
||||||
"clustering": {
|
"clustering": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"forks": "auto"
|
"forks": "auto"
|
||||||
},
|
},
|
||||||
"blockNotifyListener": {
|
|
||||||
"enabled": false,
|
|
||||||
"port": 8117,
|
|
||||||
"password": "test"
|
|
||||||
},
|
|
||||||
|
|
||||||
"redisBlockNotifyListener": {
|
|
||||||
"enabled" : false,
|
|
||||||
"redisPort" : 6379,
|
|
||||||
"redisHost" : "hostname",
|
|
||||||
"psubscribeKey" : "newblocks:*"
|
|
||||||
},
|
|
||||||
"website": {
|
"website": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"siteTitle": "Cryppit",
|
"siteTitle": "Cryppit",
|
||||||
@ -23,45 +13,54 @@
|
|||||||
"statUpdateInterval": 1.5,
|
"statUpdateInterval": 1.5,
|
||||||
"hashrateWindow": 300
|
"hashrateWindow": 300
|
||||||
},
|
},
|
||||||
/*
|
|
||||||
In a proxy configuration, you can setup ports that accept miners for work based on
|
|
||||||
a specific algorithm instead of a specific coin. Miners that connect to these ports
|
|
||||||
are automatically switched a coin determined by the server.
|
|
||||||
|
|
||||||
The default coin is the first configured pool for each algorithm and coin switching
|
"blockNotifyListener": {
|
||||||
can be triggered using the coinSwitch.js script in the scripts folder.
|
"enabled": false,
|
||||||
|
"port": 8117,
|
||||||
|
"password": "test"
|
||||||
|
},
|
||||||
|
|
||||||
|
"coinSwitchListener": {
|
||||||
|
"enabled": false,
|
||||||
|
"port": 8118,
|
||||||
|
"password": "test"
|
||||||
|
},
|
||||||
|
|
||||||
Please note miner address authentication must be disabled when using NOMP in a proxy
|
|
||||||
configuration and that payout processing is left up to the server administrator.
|
|
||||||
*/
|
|
||||||
"proxy": {
|
"proxy": {
|
||||||
"sha256": {
|
"sha256": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"port": "3333",
|
"port": "3333",
|
||||||
"diff": 10,
|
"diff": 10,
|
||||||
"varDiff": {
|
"varDiff": {
|
||||||
"minDiff": 16, //Minimum difficulty
|
"minDiff": 16,
|
||||||
"maxDiff": 512, //Network difficulty will be used if it is lower than this
|
"maxDiff": 512,
|
||||||
"targetTime": 15, //Try to get 1 share per this many seconds
|
"targetTime": 15,
|
||||||
"retargetTime": 90, //Check to see if we should retarget every this many seconds
|
"retargetTime": 90,
|
||||||
"variancePercent": 30 //Allow time to very this % from target without retargeting
|
"variancePercent": 30
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"scrypt": {
|
"scrypt": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"port": "4444",
|
"port": "4444",
|
||||||
"diff": 10,
|
"diff": 10,
|
||||||
"varDiff": {
|
"varDiff": {
|
||||||
"minDiff": 16, //Minimum difficulty
|
"minDiff": 16,
|
||||||
"maxDiff": 512, //Network difficulty will be used if it is lower than this
|
"maxDiff": 512,
|
||||||
"targetTime": 15, //Try to get 1 share per this many seconds
|
"targetTime": 15,
|
||||||
"retargetTime": 90, //Check to see if we should retarget every this many seconds
|
"retargetTime": 90,
|
||||||
"variancePercent": 30 //Allow time to very this % from target without retargeting
|
"variancePercent": 30
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"scrypt-n": {
|
"scrypt-n": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"port": "5555"
|
"port": "5555"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"redisBlockNotifyListener": {
|
||||||
|
"enabled": false,
|
||||||
|
"redisPort": 6379,
|
||||||
|
"redisHost": "hostname",
|
||||||
|
"psubscribeKey": "newblocks:*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
6
init.js
6
init.js
@ -91,11 +91,11 @@ var buildPoolConfigs = function(){
|
|||||||
|
|
||||||
var coinProfile = JSON.parse(JSON.minify(fs.readFileSync(coinFilePath, {encoding: 'utf8'})));
|
var coinProfile = JSON.parse(JSON.minify(fs.readFileSync(coinFilePath, {encoding: 'utf8'})));
|
||||||
poolOptions.coin = coinProfile;
|
poolOptions.coin = coinProfile;
|
||||||
configs[poolOptions.coin.name.toLowerCase()] = poolOptions;
|
configs[poolOptions.coin.name] = poolOptions;
|
||||||
|
|
||||||
if (!(coinProfile.algorithm in algos)){
|
if (!(coinProfile.algorithm in algos)){
|
||||||
logger.error('Master', coinProfile.name, 'Cannot run a pool for unsupported algorithm "' + coinProfile.algorithm + '"');
|
logger.error('Master', coinProfile.name, 'Cannot run a pool for unsupported algorithm "' + coinProfile.algorithm + '"');
|
||||||
delete configs[poolOptions.coin.name.toLowerCase()];
|
delete configs[poolOptions.coin.name];
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -210,7 +210,7 @@ var startCoinswitchListener = function(portalConfig){
|
|||||||
});
|
});
|
||||||
var ipcMessage = {
|
var ipcMessage = {
|
||||||
type:'switch',
|
type:'switch',
|
||||||
coin: message.coin.toLowerCase()
|
coin: message.coin
|
||||||
};
|
};
|
||||||
Object.keys(cluster.workers).forEach(function(id) {
|
Object.keys(cluster.workers).forEach(function(id) {
|
||||||
cluster.workers[id].send(ipcMessage);
|
cluster.workers[id].send(ipcMessage);
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
var Stratum = require('stratum-pool');
|
var Stratum = require('stratum-pool');
|
||||||
var Vardiff = require('stratum-pool/lib/varDiff.js');
|
|
||||||
var redis = require('redis');
|
var redis = require('redis');
|
||||||
var net = require('net');
|
var net = require('net');
|
||||||
|
|
||||||
@ -24,8 +23,15 @@ module.exports = function(logger){
|
|||||||
switch(message.type){
|
switch(message.type){
|
||||||
|
|
||||||
case 'blocknotify':
|
case 'blocknotify':
|
||||||
var pool = pools[message.coin.toLowerCase()]
|
|
||||||
if (pool) pool.processBlockNotify(message.hash)
|
var messageCoin = message.coin.toLowerCase();
|
||||||
|
var poolTarget = Object.keys(pools).filter(function(p){
|
||||||
|
return p.toLowerCase() === messageCoin;
|
||||||
|
})[0];
|
||||||
|
|
||||||
|
if (poolTarget)
|
||||||
|
pools[poolTarget].processBlockNotify(message.hash);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// IPC message for pool switching
|
// IPC message for pool switching
|
||||||
@ -34,13 +40,17 @@ module.exports = function(logger){
|
|||||||
var logComponent = 'Switch';
|
var logComponent = 'Switch';
|
||||||
var logSubCat = 'Thread ' + (parseInt(forkId) + 1);
|
var logSubCat = 'Thread ' + (parseInt(forkId) + 1);
|
||||||
|
|
||||||
var newCoin = message.coin.toLowerCase();
|
var messageCoin = message.coin.toLowerCase();
|
||||||
if (!poolConfigs.hasOwnProperty(newCoin)) {
|
var newCoin = Object.keys(pools).filter(function(p){
|
||||||
logger.debug(logSystem, logComponent, logSubCat, 'Switch message to coin that is not recognized: ' + newCoin);
|
return p.toLowerCase() === messageCoin;
|
||||||
break;
|
})[0];
|
||||||
}
|
|
||||||
|
|
||||||
var algo = poolConfigs[newCoin].coin.algorithm;
|
if (!newCoin){
|
||||||
|
logger.debug(logSystem, logComponent, logSubCat, 'Switch message to coin that is not recognized: ' + messageCoin);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var algo = poolConfigs[newCoin].coin.algorithm;
|
||||||
var newPool = pools[newCoin];
|
var newPool = pools[newCoin];
|
||||||
var oldCoin = proxySwitch[algo].currentPool;
|
var oldCoin = proxySwitch[algo].currentPool;
|
||||||
var oldPool = pools[oldCoin];
|
var oldPool = pools[oldCoin];
|
||||||
@ -168,7 +178,7 @@ module.exports = function(logger){
|
|||||||
});
|
});
|
||||||
|
|
||||||
pool.start();
|
pool.start();
|
||||||
pools[poolOptions.coin.name.toLowerCase()] = pool;
|
pools[poolOptions.coin.name] = pool;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -212,7 +222,7 @@ module.exports = function(logger){
|
|||||||
port: portalConfig.proxy[algorithm].port,
|
port: portalConfig.proxy[algorithm].port,
|
||||||
currentPool: initalPool,
|
currentPool: initalPool,
|
||||||
proxy: {}
|
proxy: {}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
// Copy diff and vardiff configuation into pools that match our algorithm so the stratum server can pick them up
|
// Copy diff and vardiff configuation into pools that match our algorithm so the stratum server can pick them up
|
||||||
@ -221,24 +231,18 @@ module.exports = function(logger){
|
|||||||
// routed into instead.
|
// routed into instead.
|
||||||
//
|
//
|
||||||
if (portalConfig.proxy[algorithm].hasOwnProperty('varDiff')) {
|
if (portalConfig.proxy[algorithm].hasOwnProperty('varDiff')) {
|
||||||
proxySwitch[algorithm].varDiff = new Vardiff(proxySwitch[algorithm].port, portalConfig.proxy[algorithm].varDiff);
|
proxySwitch[algorithm].varDiff = new Stratum.varDiff(proxySwitch[algorithm].port, portalConfig.proxy[algorithm].varDiff);
|
||||||
proxySwitch[algorithm].diff = portalConfig.proxy[algorithm].diff;
|
proxySwitch[algorithm].diff = portalConfig.proxy[algorithm].diff;
|
||||||
}
|
}
|
||||||
Object.keys(pools).forEach(function (coinName) {
|
Object.keys(pools).forEach(function (coinName) {
|
||||||
var a = poolConfigs[coinName].coin.algorithm;
|
var a = poolConfigs[coinName].coin.algorithm;
|
||||||
var p = pools[coinName];
|
var p = pools[coinName];
|
||||||
if (a == algorithm) {
|
if (a === algorithm) {
|
||||||
p.setVarDiff(proxySwitch[algorithm].port, proxySwitch[algorithm].varDiff);
|
p.setVarDiff(proxySwitch[algorithm].port, proxySwitch[algorithm].varDiff);
|
||||||
|
|
||||||
// Set diff for proxy port by mimicking coin port config and setting it in the pool
|
|
||||||
// the diff wasn't being picked up by the stratum server for proxy workers and was always using the default of 8
|
|
||||||
//p.options.ports[proxySwitch[algorithm].port] = {};
|
|
||||||
//p.options.ports[proxySwitch[algorithm].port].proxy = true;
|
|
||||||
//p.options.ports[proxySwitch[algorithm].port].diff = proxySwitch[algorithm].diff;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
proxySwitch[algorithm].proxy = net.createServer({allowHalfOpen: true}, function(socket) {
|
proxySwitch[algorithm].proxy = net.createServer(function(socket) {
|
||||||
var currentPool = proxySwitch[algorithm].currentPool;
|
var currentPool = proxySwitch[algorithm].currentPool;
|
||||||
var logSubCat = 'Thread ' + (parseInt(forkId) + 1);
|
var logSubCat = 'Thread ' + (parseInt(forkId) + 1);
|
||||||
|
|
||||||
|
|||||||
@ -18,7 +18,7 @@ module.exports = function(logger, poolConfig){
|
|||||||
|
|
||||||
var internalConfig = poolConfig.shareProcessing.internal;
|
var internalConfig = poolConfig.shareProcessing.internal;
|
||||||
var redisConfig = internalConfig.redis;
|
var redisConfig = internalConfig.redis;
|
||||||
var coin = poolConfig.coin.name.toLowerCase();
|
var coin = poolConfig.coin.name;
|
||||||
|
|
||||||
var forkId = process.env.forkId;
|
var forkId = process.env.forkId;
|
||||||
var logSystem = 'Pool';
|
var logSystem = 'Pool';
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"enabled": false,
|
"enabled": true,
|
||||||
"coin": "litecoin.json",
|
"coin": "litecoin.json",
|
||||||
|
|
||||||
"address": "n4jSe18kZMCdGcZqaYprShXW6EH1wivUK1",
|
"address": "n4jSe18kZMCdGcZqaYprShXW6EH1wivUK1",
|
||||||
|
|||||||
@ -1,21 +1,20 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
This script should be hooked to the coin daemon as follow:
|
This script should be hooked to the coin daemon as follow:
|
||||||
litecoind -blocknotify="node /path/to/this/script/blockNotify.js localhost:8117 password litecoin %s"
|
litecoind -blocknotify="node /path/to/this/script/blockNotify.js localhost:8117 password litecoin %s"
|
||||||
The above will send tell litecoin to launch this script with those parameters every time a block is found.
|
The above will send tell litecoin to launch this script with those parameters every time a block is found.
|
||||||
This script will then send the blockhash along with other information to a listening tcp socket
|
This script will then send the blockhash along with other information to a listening tcp socket
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var net = require('net');
|
var net = require('net');
|
||||||
var config = process.argv[2];
|
var config = process.argv[2];
|
||||||
var parts = config.split(':');
|
var parts = config.split(':');
|
||||||
var host = parts[0];
|
var host = parts[0];
|
||||||
var port = parts[1];
|
var port = parts[1];
|
||||||
var password = process.argv[3];
|
var password = process.argv[3];
|
||||||
var coin = process.argv[4];
|
var coin = process.argv[4];
|
||||||
var blockHash = process.argv[5];
|
var blockHash = process.argv[5];
|
||||||
|
|
||||||
var client = net.connect(port, host, function() {
|
var client = net.connect(port, host, function () {
|
||||||
console.log('client connected');
|
console.log('client connected');
|
||||||
client.write(JSON.stringify({
|
client.write(JSON.stringify({
|
||||||
password: password,
|
password: password,
|
||||||
@ -24,12 +23,12 @@ var client = net.connect(port, host, function() {
|
|||||||
}) + '\n');
|
}) + '\n');
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on('data', function(data) {
|
client.on('data', function (data) {
|
||||||
console.log(data.toString());
|
console.log(data.toString());
|
||||||
//client.end();
|
//client.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on('end', function() {
|
client.on('end', function () {
|
||||||
console.log('client disconnected');
|
console.log('client disconnected');
|
||||||
//process.exit();
|
//process.exit();
|
||||||
});
|
});
|
||||||
@ -1,38 +1,37 @@
|
|||||||
/*
|
/*
|
||||||
This script demonstrates sending a coin switch request and can be invoked from the command line
|
This script demonstrates sending a coin switch request and can be invoked from the command line
|
||||||
with:
|
with:
|
||||||
|
|
||||||
"node coinSwitch.js localhost:8118 password %s"
|
"node coinSwitch.js localhost:8118 password %s"
|
||||||
|
|
||||||
where <%s> is the name of the coin proxy miners will be switched onto.
|
where <%s> is the name of the coin proxy miners will be switched onto.
|
||||||
|
|
||||||
If the coin name is not configured, disabled or matches the existing proxy setting, no action
|
If the coin name is not configured, disabled or matches the existing proxy setting, no action
|
||||||
will be taken by NOMP on receipt of the message.
|
will be taken by NOMP on receipt of the message.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var net = require('net');
|
var net = require('net');
|
||||||
var config = process.argv[2];
|
var config = process.argv[2];
|
||||||
var parts = config.split(':');
|
var parts = config.split(':');
|
||||||
var host = parts[0];
|
var host = parts[0];
|
||||||
var port = parts[1];
|
var port = parts[1];
|
||||||
var password = process.argv[3];
|
var password = process.argv[3];
|
||||||
var coin = process.argv[4];
|
var coin = process.argv[4];
|
||||||
var blockHash = process.argv[5];
|
|
||||||
|
|
||||||
var client = net.connect(port, host, function() {
|
var client = net.connect(port, host, function () {
|
||||||
console.log('client connected');
|
console.log('client connected');
|
||||||
client.write(JSON.stringify({
|
client.write(JSON.stringify({
|
||||||
password: password,
|
password: password,
|
||||||
coin: coin,
|
coin: coin
|
||||||
}) + '\n');
|
}) + '\n');
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on('data', function(data) {
|
client.on('data', function (data) {
|
||||||
console.log(data.toString());
|
console.log(data.toString());
|
||||||
//client.end();
|
//client.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on('end', function() {
|
client.on('end', function () {
|
||||||
console.log('client disconnected');
|
console.log('client disconnected');
|
||||||
//process.exit();
|
//process.exit();
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user