mirror of https://github.com/BTCPrivate/z-nomp.git
Changed all references to localhost to 127.0.0.1 for better system compatibility. Implemented thread-wide IP banning via IPC. Added redis config for portal-wide related db interactions (stats and proxy)
This commit is contained in:
parent
790cffb0c4
commit
4888aaffba
78
README.md
78
README.md
|
@ -2,10 +2,34 @@
|
|||
#### Node Open Mining Portal
|
||||
|
||||
This portal is an extremely efficient, highly scalable, all-in-one, easy to setup cryptocurrency mining pool written
|
||||
entirely in Node.js. It contains a stratum poolserver, reward/payment/share processor, and a (*not yet completed*)
|
||||
front-end website.
|
||||
entirely in Node.js. It contains a stratum poolserver; reward/payment/share processor; and a (*not yet completed*)
|
||||
responsive user-friendly front-end website featuring mining instructions, in-depth live statistics, and an admin center.
|
||||
|
||||
#### Features
|
||||
#### Table of Contents
|
||||
* [Features](#features)
|
||||
* [Attack Mitigation](##attack-mitigation)
|
||||
* [Security](#security)
|
||||
* [Planned Features](#planned-features)
|
||||
* [Community Support](#community--support)
|
||||
* [Usage](#usage)
|
||||
* [Requirements](#requirements)
|
||||
* [Setting Up Coin Daemon](#0-setting-up-coin-daemon)
|
||||
* [Downloading & Installing](#1-downloading--installing)
|
||||
* [Configuration](#2-configuration)
|
||||
* [Portal Config](#portal-config)
|
||||
* [Coin Config](#coin-config)
|
||||
* [Pool Config](#pool-config)
|
||||
* [Setting Up Blocknotify](#optional-recommended-setting-up-blocknotify)
|
||||
* [Starting the Portal](#3-start-the-portal)
|
||||
* [Upgrading NOMP](#upgrading-nomp)
|
||||
* [Donations](#donations)
|
||||
* [Credits](#credits)
|
||||
* [License](#license)
|
||||
|
||||
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* For the pool server it uses the highly efficient [node-stratum-pool](//github.com/zone117x/node-stratum-pool) module which
|
||||
supports vardiff, POW & POS, transaction messages, anti-DDoS, IP banning, [several hashing algorithms](//github.com/zone117x/node-stratum-pool#hashing-algorithms-supported).
|
||||
|
@ -64,7 +88,7 @@ allow your own pool to connect upstream to a larger pool server. It will request
|
|||
redistribute the work to our own connected miners.
|
||||
|
||||
|
||||
#### Community / Support
|
||||
### Community / Support
|
||||
IRC
|
||||
* Support / general discussion join #nomp: https://webchat.freenode.net/?channels=#nomp
|
||||
* Development discussion join #nomp-dev: https://webchat.freenode.net/?channels=#nomp-dev
|
||||
|
@ -80,8 +104,11 @@ If your pool uses NOMP let us know and we will list your website here.
|
|||
* http://chunkypools.com
|
||||
* http://clevermining.com
|
||||
* http://rapidhash.net
|
||||
* http://suchpool.pw
|
||||
* http://hashfaster.com
|
||||
* http://miningpoolhub.com
|
||||
* http://kryptochaos.com
|
||||
* http://pool.uberpools.org
|
||||
|
||||
|
||||
Usage
|
||||
|
@ -156,12 +183,7 @@ Explanation for each field:
|
|||
/* How many seconds to hold onto historical stats. Currently set to 24 hours. */
|
||||
"historicalRetention": 43200,
|
||||
/* How many seconds worth of shares should be gathered to generate hashrate. */
|
||||
"hashrateWindow": 300,
|
||||
/* Redis instance of where to store historical stats. */
|
||||
"redis": {
|
||||
"host": "localhost",
|
||||
"port": 6379
|
||||
}
|
||||
"hashrateWindow": 300
|
||||
},
|
||||
/* Not done yet. */
|
||||
"adminCenter": {
|
||||
|
@ -170,6 +192,13 @@ Explanation for each field:
|
|||
}
|
||||
},
|
||||
|
||||
/* Redis instance of where to store global portal data such as historical stats, proxy states,
|
||||
ect.. */
|
||||
"redis": {
|
||||
"host": "127.0.0.1",
|
||||
"port": 6379
|
||||
},
|
||||
|
||||
/* 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
|
||||
|
@ -290,6 +319,12 @@ Description of options:
|
|||
due to mining apps using incorrect max diffs and this pool using correct max diffs. */
|
||||
"shareVariancePercent": 10,
|
||||
|
||||
/* Enable for client IP addresses to be detected when using a load balancer with TCP proxy
|
||||
protocol enabled, such as HAProxy with 'send-proxy' param:
|
||||
http://haproxy.1wt.eu/download/1.5/doc/configuration.txt */
|
||||
"tcpProxyProtocol": false,
|
||||
|
||||
|
||||
/* This determines what to do with submitted shares (and stratum worker authentication).
|
||||
You have two options:
|
||||
1) Enable internal and disable mpos = this portal to handle all share payments.
|
||||
|
@ -338,7 +373,7 @@ Description of options:
|
|||
configured 'address' that receives the block rewards, otherwise the daemon will not
|
||||
be able to confirm blocks or send out payments. */
|
||||
"daemon": {
|
||||
"host": "localhost",
|
||||
"host": "127.0.0.1",
|
||||
"port": 19332,
|
||||
"user": "litecoinrpc",
|
||||
"password": "testnet"
|
||||
|
@ -346,7 +381,7 @@ Description of options:
|
|||
|
||||
/* Redis database used for storing share and block submission data. */
|
||||
"redis": {
|
||||
"host": "localhost",
|
||||
"host": "127.0.0.1",
|
||||
"port": 6379
|
||||
}
|
||||
},
|
||||
|
@ -355,7 +390,7 @@ Description of options:
|
|||
also want to use the "emitInvalidBlockHashes" option below if you require it. */
|
||||
"mpos": {
|
||||
"enabled": false,
|
||||
"host": "localhost", //MySQL db host
|
||||
"host": "127.0.0.1", //MySQL db host
|
||||
"port": 3306, //MySQL db port
|
||||
"user": "me", //MySQL db user
|
||||
"password": "mypass", //MySQL db password
|
||||
|
@ -368,8 +403,10 @@ Description of options:
|
|||
}
|
||||
},
|
||||
|
||||
/* If a worker is submitting a high threshold of invalid shares we can temporarily ban them
|
||||
to reduce system/network load. Also useful to fight against flooding attacks. */
|
||||
/* If a worker is submitting a high threshold of invalid shares we can temporarily ban their IP
|
||||
to reduce system/network load. Also useful to fight against flooding attacks. The worker's
|
||||
If running behind something like HAProxy be sure to enable the TCP Proxy Protocol config,
|
||||
otherwise you'll end up banning your own IP address (and therefore all workers). */
|
||||
"banning": {
|
||||
"enabled": true,
|
||||
"time": 600, //How many seconds to ban worker for
|
||||
|
@ -404,13 +441,13 @@ Description of options:
|
|||
drops out-of-sync or offline. */
|
||||
"daemons": [
|
||||
{ //Main daemon instance
|
||||
"host": "localhost",
|
||||
"host": "127.0.0.1",
|
||||
"port": 19332,
|
||||
"user": "litecoinrpc",
|
||||
"password": "testnet"
|
||||
},
|
||||
{ //Backup daemon instance
|
||||
"host": "localhost",
|
||||
"host": "127.0.0.1",
|
||||
"port": 19344,
|
||||
"user": "litecoinrpc",
|
||||
"password": "testnet"
|
||||
|
@ -423,7 +460,7 @@ Description of options:
|
|||
intensive than blocknotify script). However its still under development (not yet working). */
|
||||
"p2p": {
|
||||
"enabled": false,
|
||||
"host": "localhost",
|
||||
"host": "127.0.0.1",
|
||||
"port": 19333,
|
||||
|
||||
/* Magic value is different for main/testnet and for each coin. It is found in the daemon
|
||||
|
@ -455,7 +492,7 @@ node [path to scripts/blockNotify.js] [listener host]:[listener port] [listener
|
|||
```
|
||||
Example: inside `dogecoin.conf` add the line
|
||||
```
|
||||
blocknotify="node scripts/blockNotify.js localhost:8117 mySuperSecurePassword dogecoin %s"
|
||||
blocknotify="node scripts/blockNotify.js 127.0.0.1:8117 mySuperSecurePassword dogecoin %s"
|
||||
```
|
||||
|
||||
Alternatively, you can use a more efficient block notify script written in pure C. Build and usage instructions
|
||||
|
@ -506,7 +543,8 @@ Credits
|
|||
* [TheSeven](//github.com/TheSeven) - answering an absurd amount of my questions and being a very helpful gentleman
|
||||
* [UdjinM6](//github.com/UdjinM6) - helped implement fee withdrawal in payment processing
|
||||
* [Alex Petrov / sysmanalex](https://github.com/sysmanalex) - contributed the pure C block notify script
|
||||
* Those that contributed to [node-stratum-pool](//github.com/zone117x/node-stratum-pool)
|
||||
* [svirusxxx](//github.com/svirusxxx) - sponsored development of MPOS mode
|
||||
* Those that contributed to [node-stratum-pool](//github.com/zone117x/node-stratum-pool#credits)
|
||||
|
||||
|
||||
License
|
||||
|
|
|
@ -13,11 +13,7 @@
|
|||
"stats": {
|
||||
"updateInterval": 60,
|
||||
"historicalRetention": 43200,
|
||||
"hashrateWindow": 300,
|
||||
"redis": {
|
||||
"host": "localhost",
|
||||
"port": 6379
|
||||
}
|
||||
"hashrateWindow": 300
|
||||
},
|
||||
"adminCenter": {
|
||||
"enabled": true,
|
||||
|
@ -25,6 +21,11 @@
|
|||
}
|
||||
},
|
||||
|
||||
"redis": {
|
||||
"host": "127.0.0.1",
|
||||
"port": 6379
|
||||
},
|
||||
|
||||
"blockNotifyListener": {
|
||||
"enabled": false,
|
||||
"port": 8117,
|
||||
|
|
23
init.js
23
init.js
|
@ -8,7 +8,6 @@ var PoolLogger = require('./libs/logUtil.js');
|
|||
var BlocknotifyListener = require('./libs/blocknotifyListener.js');
|
||||
var CoinswitchListener = require('./libs/coinswitchListener.js');
|
||||
var RedisBlocknotifyListener = require('./libs/redisblocknotifyListener.js');
|
||||
var WorkerListener = require('./libs/workerListener.js');
|
||||
var PoolWorker = require('./libs/poolWorker.js');
|
||||
var PaymentProcessor = require('./libs/paymentProcessor.js');
|
||||
var Website = require('./libs/website.js');
|
||||
|
@ -139,6 +138,7 @@ var spawnPoolWorkers = function(portalConfig, poolConfigs){
|
|||
return portalConfig.clustering.forks;
|
||||
})();
|
||||
|
||||
var poolWorkers = {};
|
||||
|
||||
var createPoolWorker = function(forkId){
|
||||
var worker = cluster.fork({
|
||||
|
@ -147,11 +147,24 @@ var spawnPoolWorkers = function(portalConfig, poolConfigs){
|
|||
pools: serializedConfigs,
|
||||
portalConfig: JSON.stringify(portalConfig)
|
||||
});
|
||||
worker.forkId = forkId;
|
||||
worker.type = 'pool';
|
||||
poolWorkers[forkId] = worker;
|
||||
worker.on('exit', function(code, signal){
|
||||
logger.error('Master', 'PoolSpanwer', 'Fork ' + forkId + ' died, spawning replacement worker...');
|
||||
setTimeout(function(){
|
||||
createPoolWorker(forkId);
|
||||
}, 2000);
|
||||
}).on('message', function(msg){
|
||||
switch(msg.type){
|
||||
case 'banIP':
|
||||
Object.keys(cluster.workers).forEach(function(id) {
|
||||
if (cluster.workers[id].type === 'pool'){
|
||||
cluster.workers[id].send({type: 'banIP', ip: msg.ip});
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -168,12 +181,6 @@ var spawnPoolWorkers = function(portalConfig, poolConfigs){
|
|||
};
|
||||
|
||||
|
||||
var startWorkerListener = function(poolConfigs){
|
||||
var workerListener = new WorkerListener(logger, poolConfigs);
|
||||
workerListener.init();
|
||||
};
|
||||
|
||||
|
||||
var startBlockListener = function(portalConfig){
|
||||
//block notify options
|
||||
//setup block notify here and use IPC to tell appropriate pools
|
||||
|
@ -301,8 +308,6 @@ var startWebsite = function(portalConfig, poolConfigs){
|
|||
|
||||
startRedisBlockListener(portalConfig);
|
||||
|
||||
startWorkerListener(poolConfigs);
|
||||
|
||||
startWebsite(portalConfig, poolConfigs);
|
||||
|
||||
})();
|
||||
|
|
|
@ -41,7 +41,7 @@ module.exports = function(logger, poolConfig){
|
|||
|
||||
connection.query(
|
||||
'SELECT password FROM pool_worker WHERE username = LOWER(?)',
|
||||
[workerName],
|
||||
[workerName.toLowerCase()],
|
||||
function(err, result){
|
||||
if (err){
|
||||
logger.error(logIdentify, logComponent, 'Database error when authenticating worker: ' +
|
||||
|
|
|
@ -22,6 +22,13 @@ module.exports = function(logger){
|
|||
process.on('message', function(message) {
|
||||
switch(message.type){
|
||||
|
||||
case 'banIP':
|
||||
for (var p in pools){
|
||||
if (pools[p].stratumServer)
|
||||
pools[p].stratumServer.addBannedIP(message.ip);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'blocknotify':
|
||||
|
||||
var messageCoin = message.coin.toLowerCase();
|
||||
|
@ -75,7 +82,7 @@ module.exports = function(logger){
|
|||
);
|
||||
proxySwitch[algo].currentPool = newCoin;
|
||||
|
||||
var redisClient = redis.createClient(6379, "localhost")
|
||||
var redisClient = redis.createClient(portalConfig.redis.port, portalConfig.redis.host)
|
||||
redisClient.on('ready', function(){
|
||||
redisClient.hset('proxyState', algo, newCoin, function(error, obj) {
|
||||
if (error) {
|
||||
|
@ -186,6 +193,8 @@ module.exports = function(logger){
|
|||
handlers.diff(workerName, diff);
|
||||
}).on('log', function(severity, text) {
|
||||
logger[severity](logSystem, logComponent, logSubCat, text);
|
||||
}).on('banIP', function(ip, worker){
|
||||
process.send({type: 'banIP', ip: ip});
|
||||
});
|
||||
|
||||
pool.start();
|
||||
|
@ -206,7 +215,7 @@ module.exports = function(logger){
|
|||
// on the last pool it was using when reloaded or restarted
|
||||
//
|
||||
logger.debug(logSystem, logComponent, logSubCat, 'Loading last proxy state from redis');
|
||||
var redisClient = redis.createClient(6379, "localhost")
|
||||
var redisClient = redis.createClient(portalConfig.redis.port, portalConfig.redis.host)
|
||||
redisClient.on('ready', function(){
|
||||
redisClient.hgetall("proxyState", function(error, obj) {
|
||||
if (error || obj == null) {
|
||||
|
|
|
@ -59,7 +59,7 @@ module.exports = function(logger, portalConfig, poolConfigs){
|
|||
|
||||
|
||||
function setupStatsRedis(){
|
||||
redisStats = redis.createClient(portalConfig.website.stats.redis.port, portalConfig.website.stats.redis.host);
|
||||
redisStats = redis.createClient(portalConfig.redis.port, portalConfig.redis.host);
|
||||
redisStats.on('error', function(err){
|
||||
logger.error(logSystem, 'Historics', 'Redis for stats had an error ' + JSON.stringify(err));
|
||||
});
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
var events = require('events');
|
||||
var cluster = require('cluster');
|
||||
|
||||
var MposCompatibility = require('./mposCompatibility.js');
|
||||
var ShareProcessor = require('./shareProcessor.js');
|
||||
|
||||
|
||||
var processor = module.exports = function processor(logger, poolConfigs){
|
||||
|
||||
var _this = this;
|
||||
|
||||
|
||||
this.init = function(){
|
||||
|
||||
Object.keys(cluster.workers).forEach(function(id) {
|
||||
cluster.workers[id].on('message', function(data){
|
||||
switch(data.type){
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
processor.prototype.__proto__ = events.EventEmitter.prototype;
|
|
@ -10,6 +10,8 @@
|
|||
"emitInvalidBlockHashes": false,
|
||||
"shareVariancePercent": 15,
|
||||
|
||||
"tcpProxyProtocol": false,
|
||||
|
||||
"shareProcessing": {
|
||||
"internal": {
|
||||
"enabled": true,
|
||||
|
@ -22,19 +24,19 @@
|
|||
"feeReceiveAddress": "mppaGeNaSbG1Q7S6V3gL5uJztMhucgL9Vh",
|
||||
"feeWithdrawalThreshold": 5,
|
||||
"daemon": {
|
||||
"host": "localhost",
|
||||
"host": "127.0.0.1",
|
||||
"port": 19332,
|
||||
"user": "litecoinrpc",
|
||||
"password": "testnet"
|
||||
},
|
||||
"redis": {
|
||||
"host": "localhost",
|
||||
"host": "127.0.0.1",
|
||||
"port": 6379
|
||||
}
|
||||
},
|
||||
"mpos": {
|
||||
"enabled": false,
|
||||
"host": "localhost",
|
||||
"host": "127.0.0.1",
|
||||
"port": 3306,
|
||||
"user": "me",
|
||||
"password": "mypass",
|
||||
|
@ -72,13 +74,13 @@
|
|||
|
||||
"daemons": [
|
||||
{
|
||||
"host": "localhost",
|
||||
"host": "127.0.0.1",
|
||||
"port": 19332,
|
||||
"user": "litecoinrpc",
|
||||
"password": "testnet"
|
||||
},
|
||||
{
|
||||
"host": "localhost",
|
||||
"host": "127.0.0.1",
|
||||
"port": 19344,
|
||||
"user": "litecoinrpc",
|
||||
"password": "testnet"
|
||||
|
@ -87,7 +89,7 @@
|
|||
|
||||
"p2p": {
|
||||
"enabled": false,
|
||||
"host": "localhost",
|
||||
"host": "127.0.0.1",
|
||||
"port": 19333,
|
||||
"protocolVersion": 70002,
|
||||
"magic": "fcc1b7dc"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
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 127.0.0.1:8117 password litecoin %s"
|
||||
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
|
||||
*/
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
This script demonstrates sending a coin switch request and can be invoked from the command line
|
||||
with:
|
||||
|
||||
"node coinSwitch.js localhost:8118 password %s"
|
||||
"node coinSwitch.js 127.0.0.1:8118 password %s"
|
||||
|
||||
where <%s> is the name of the coin proxy miners will be switched onto.
|
||||
|
||||
|
|
Loading…
Reference in New Issue