Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f3a1bc63e | ||
|
|
81216de5dd | ||
|
|
f185e971c4 | ||
|
|
d55efbd227 | ||
|
|
53432ba8fe | ||
|
|
4ebff37820 | ||
|
|
2061e666c9 | ||
|
|
0b238adccd | ||
|
|
e41cb8d8f4 | ||
|
|
67254f63ba | ||
|
|
8a725c0438 | ||
|
|
f83f5b371b | ||
|
|
f84ee142c2 |
27
README.md
27
README.md
@ -1,3 +1,8 @@
|
||||
## This repo is looking for maintainers! Please reach out if interested.
|
||||
|
||||
--------
|
||||
|
||||
|
||||
# NOMP 
|
||||
#### Node Open Mining Portal
|
||||
|
||||
@ -8,6 +13,12 @@ responsive user-friendly front-end website featuring mining instructions, in-dep
|
||||
#### Production Usage Notice
|
||||
This is beta software. All of the following are things that can change and break an existing NOMP setup: functionality of any feature, structure of configuration files and structure of redis data. If you use this software in production then *DO NOT* pull new code straight into production usage because it can and often will break your setup and require you to tweak things like config files or redis data.
|
||||
|
||||
#### Paid Solution
|
||||
Usage of this software requires abilities with sysadmin, database admin, coin daemons, and sometimes a bit of programming. Running a production pool can literally be more work than a full-time job.
|
||||
|
||||
|
||||
**Coin switching & auto-exchanging for payouts in BTC/LTC** to miners is a feature that very likely will not be included in this project.
|
||||
|
||||
|
||||
#### Table of Contents
|
||||
* [Features](#features)
|
||||
@ -104,21 +115,13 @@ didn't follow the instructions in this README. Please __read the usage instructi
|
||||
If your pool uses NOMP let us know and we will list your website here.
|
||||
|
||||
##### Some pools using NOMP or node-stratum-module:
|
||||
* http://chunkypools.com
|
||||
* http://clevermining.com
|
||||
* http://rapidhash.net
|
||||
* http://suchpool.pw
|
||||
* http://hashfaster.com
|
||||
* http://miningpoolhub.com
|
||||
* http://teamdoge.com
|
||||
* http://miningwith.us
|
||||
* http://kryptochaos.com
|
||||
* http://uberpools.org
|
||||
* http://onebtcplace.com
|
||||
* http://minr.es
|
||||
* http://mining.theminingpools.com
|
||||
* http://www.omargpools.ca/pools.html
|
||||
* http://pool.trademybit.com/
|
||||
* http://miningpools.tk
|
||||
* http://umine.co.uk
|
||||
|
||||
Usage
|
||||
=====
|
||||
@ -348,7 +351,7 @@ Here is an example of the required fields:
|
||||
source code as the pchMessageStart variable.
|
||||
For example, litecoin mainnet magic: http://git.io/Bi8YFw
|
||||
And for litecoin testnet magic: http://git.io/NXBYJA */
|
||||
"peerMagic": "fbc0b6db" //optional
|
||||
"peerMagic": "fbc0b6db", //optional
|
||||
"peerMagicTestnet": "fcc1b7dc" //optional
|
||||
|
||||
//"txMessages": false, //options - defaults to false
|
||||
@ -524,7 +527,7 @@ output from NOMP.
|
||||
|
||||
#### Upgrading NOMP
|
||||
When updating NOMP to the latest code its important to not only `git pull` the latest from this repo, but to also update
|
||||
the `node-statum-pool` and `node-multi-hashing` modules, and any config files that may have been changed.
|
||||
the `node-stratum-pool` and `node-multi-hashing` modules, and any config files that may have been changed.
|
||||
* Inside your NOMP directory (where the init.js script is) do `git pull` to get the latest NOMP code.
|
||||
* Remove the dependenices by deleting the `node_modules` directory with `rm -r node_modules`.
|
||||
* Run `npm update` to force updating/reinstalling of the dependencies.
|
||||
|
||||
25
coins/00_example.json
Normal file
25
coins/00_example.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "Example",
|
||||
"symbol": "EXM",
|
||||
"algorithm": "x99",
|
||||
"peerMagic": "0f0f0f0f",
|
||||
"peerMagicTestnet": "f0f0f0f0",
|
||||
|
||||
"mainnet": {
|
||||
"bech32": "ex",
|
||||
"bip32": {
|
||||
"public": "0f0f0f0f"
|
||||
},
|
||||
"pubKeyHash": "00",
|
||||
"scriptHash": "ff"
|
||||
},
|
||||
|
||||
"testnet": {
|
||||
"bech32": "tex",
|
||||
"bip32": {
|
||||
"public": "f0f0f0f0"
|
||||
},
|
||||
"pubKeyHash": "0f",
|
||||
"scriptHash": "f0"
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,7 @@
|
||||
{
|
||||
"name": "21coin",
|
||||
"symbol": "21",
|
||||
"algorithm": "sha256"
|
||||
"algorithm": "sha256", │·····································
|
||||
"peerMagic": "21212121", │·····································
|
||||
"peerMagicTestnet": "01fefe05"
|
||||
}
|
||||
|
||||
5
coins/42.json
Normal file
5
coins/42.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "42",
|
||||
"symbol": "42",
|
||||
"algorithm": "scrypt"
|
||||
}
|
||||
@ -1,5 +1,7 @@
|
||||
{
|
||||
"name": "Alphacoin",
|
||||
"symbol": "ALF",
|
||||
"algorithm": "scrypt"
|
||||
"algorithm": "scrypt",
|
||||
"peerMagic": "fbc0b6db",
|
||||
"peerMagicTestnet": "fcc1b7dc"
|
||||
}
|
||||
@ -1,5 +1,7 @@
|
||||
{
|
||||
"name": "Benjamins",
|
||||
"symbol": "BEN",
|
||||
"algorithm": "sha256"
|
||||
"algorithm": "sha256",
|
||||
"peerMagic": "de698778", │·····································
|
||||
"peerMagicTestnet": "0b110907"
|
||||
}
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
{
|
||||
"name": "Bottlecaps",
|
||||
"symbol": "CAP",
|
||||
"algorithm": "scrypt"
|
||||
"algorithm": "scrypt",
|
||||
"peerMagic": "e4e8e9e5",
|
||||
"peerMagicTestnet": "cdf2c0ef"
|
||||
}
|
||||
7
coins/bunnycoin.json
Normal file
7
coins/bunnycoin.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "BunnyCoin",
|
||||
"symbol": "BUN",
|
||||
"algorithm": "scrypt",
|
||||
"peerMagic": "c0c0c0c0",
|
||||
"peerMagicTestnet": "fcc1b7dc"
|
||||
}
|
||||
@ -1,5 +1,7 @@
|
||||
{
|
||||
"name": "Casinocoin",
|
||||
"symbol": "CSC",
|
||||
"algorithm": "scrypt"
|
||||
"algorithm": "scrypt",
|
||||
"peerMagic": "fac3b6da",
|
||||
"peerMagicTestnet": "fcc1b7dc"
|
||||
}
|
||||
25
coins/chaincoin.json
Normal file
25
coins/chaincoin.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "Chaincoin",
|
||||
"symbol": "CHC",
|
||||
"algorithm": "c11",
|
||||
"peerMagic": "a3d27a03",
|
||||
"peerMagicTestnet": "fbc21102",
|
||||
|
||||
"mainnet": {
|
||||
"bech32": "chc",
|
||||
"bip32": {
|
||||
"public": "0488b21e"
|
||||
},
|
||||
"pubKeyHash": "1c",
|
||||
"scriptHash": "04"
|
||||
},
|
||||
|
||||
"testnet": {
|
||||
"bech32": "tchc",
|
||||
"bip32": {
|
||||
"public": "043587cf"
|
||||
},
|
||||
"pubKeyHash": "50",
|
||||
"scriptHash": "2c"
|
||||
}
|
||||
}
|
||||
7
coins/coino.json
Normal file
7
coins/coino.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "Coino",
|
||||
"symbol": "COINO",
|
||||
"algorithm": "scrypt",
|
||||
"peerMagic": "f1d1a7d8",
|
||||
"peerMagicTestnet": "fcc1b7dc"
|
||||
}
|
||||
7
coins/cryptogenicbullion.json
Normal file
7
coins/cryptogenicbullion.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "CryptogenicBullion",
|
||||
"symbol": "CGB",
|
||||
"algorithm": "scrypt",
|
||||
"peerMagic": "e4e8e9e5",
|
||||
"peerMagicTestnet": "cdf2c0ef"
|
||||
}
|
||||
7
coins/cryptographicanomaly.json
Normal file
7
coins/cryptographicanomaly.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "CryptographicAnomaly",
|
||||
"symbol": "CGA",
|
||||
"algorithm": "scrypt",
|
||||
"peerMagic": "fbc0b6db",
|
||||
"peerMagicTestnet": "fcc1b7dc"
|
||||
}
|
||||
@ -1,5 +1,7 @@
|
||||
{
|
||||
"name": "Digibyte",
|
||||
"symbol": "DGB",
|
||||
"algorithm": "scrypt"
|
||||
"algorithm": "scrypt",
|
||||
"peerMagic": "fac3b6da",
|
||||
"peerMagicTestnet": "fdc8bddd"
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
{
|
||||
"name": "eMark",
|
||||
"symbol": "DEM",
|
||||
"algorithm": "sha256"
|
||||
"algorithm": "sha256",
|
||||
"reward": "POS"
|
||||
}
|
||||
|
||||
5
coins/fluttercoin.json
Normal file
5
coins/fluttercoin.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "FlutterCoin",
|
||||
"symbol": "FLT",
|
||||
"algorithm": "scrypt"
|
||||
}
|
||||
7
coins/globaltoken.json
Normal file
7
coins/globaltoken.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "GlobalToken",
|
||||
"symbol": "GLT",
|
||||
"algorithm": "sha256",
|
||||
"peerMagic": "c708d32d",
|
||||
"peerMagicTestnet": "3a6f375b"
|
||||
}
|
||||
7
coins/infinitecoin.conf
Normal file
7
coins/infinitecoin.conf
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "Infinitecoin",
|
||||
"symbol": "IFC",
|
||||
"algorithm": "scrypt",
|
||||
"peerMagic": "fbc0b6db",
|
||||
"peerMagicTestnet": "fcc1b7dc"
|
||||
}
|
||||
6
coins/kumacoin.json
Normal file
6
coins/kumacoin.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "Kumacoin",
|
||||
"symbol": "KUMA",
|
||||
"algorithm": "quark",
|
||||
"mposDiffMultiplier": 256
|
||||
}
|
||||
@ -1,7 +1,25 @@
|
||||
{
|
||||
"name": "Litecoin",
|
||||
"symbol": "LTC",
|
||||
"algorithm": "scrypt",
|
||||
"peerMagic": "fbc0b6db",
|
||||
"peerMagicTestnet": "fcc1b7dc"
|
||||
"name": "Litecoin",
|
||||
"symbol": "LTC",
|
||||
"algorithm": "scrypt",
|
||||
"peerMagic": "fbc0b6db",
|
||||
"peerMagicTestnet": "fdd2c8f1",
|
||||
|
||||
"mainnet": {
|
||||
"bech32": "ltc",
|
||||
"bip32": {
|
||||
"public": "0488B21E"
|
||||
},
|
||||
"pubKeyHash": "30",
|
||||
"scriptHash": "05"
|
||||
},
|
||||
|
||||
"testnet": {
|
||||
"bech32": "tltc",
|
||||
"bip32": {
|
||||
"public": "043587CF"
|
||||
},
|
||||
"pubKeyHash": "6F",
|
||||
"scriptHash": "C4"
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,7 @@
|
||||
{
|
||||
"name": "Mazacoin",
|
||||
"symbol": "MZC",
|
||||
"algorithm": "sha256"
|
||||
"algorithm": "sha256",
|
||||
"peerMagic": "f8b503df", │·····································
|
||||
"peerMagicTestnet": "05fea901"
|
||||
}
|
||||
|
||||
5
coins/monacoin.json
Normal file
5
coins/monacoin.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "Monacoin",
|
||||
"symbol": "MONA",
|
||||
"algorithm": "scrypt"
|
||||
}
|
||||
5
coins/sayacoin.json
Normal file
5
coins/sayacoin.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "Sayacoin",
|
||||
"symbol": "SYC",
|
||||
"algorithm": "sha256"
|
||||
}
|
||||
5
coins/sha1coin.json
Normal file
5
coins/sha1coin.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "Sha1coin",
|
||||
"symbol": "SHA",
|
||||
"algorithm": "sha1coin"
|
||||
}
|
||||
7
coins/viacoin.json
Normal file
7
coins/viacoin.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "Viacoin",
|
||||
"symbol": "VIA",
|
||||
"algorithm": "scrypt",
|
||||
"peerMagic": "0f68c6cb",
|
||||
"peerMagicTestnet": "a9c5ef92"
|
||||
}
|
||||
31
init.js
31
init.js
@ -82,6 +82,10 @@ if (cluster.isWorker){
|
||||
case 'profitSwitch':
|
||||
new ProfitSwitch(logger);
|
||||
break;
|
||||
case 'switchingPaymentProcessor':
|
||||
var SwitchingPaymentProcessor = require('./libs/switchingPaymentProcessor.js');
|
||||
new SwitchingPaymentProcessor(logger);
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
@ -143,6 +147,17 @@ var buildPoolConfigs = function(){
|
||||
var coinProfile = JSON.parse(JSON.minify(fs.readFileSync(coinFilePath, {encoding: 'utf8'})));
|
||||
poolOptions.coin = coinProfile;
|
||||
poolOptions.coin.name = poolOptions.coin.name.toLowerCase();
|
||||
if (coinProfile.mainnet) {
|
||||
poolOptions.coin.mainnet.bip32.public = Buffer.from(coinProfile.mainnet.bip32.public, 'hex').readUInt32LE(0);
|
||||
poolOptions.coin.mainnet.pubKeyHash = Buffer.from(coinProfile.mainnet.pubKeyHash, 'hex').readUInt8(0);
|
||||
poolOptions.coin.mainnet.scriptHash = Buffer.from(coinProfile.mainnet.scriptHash, 'hex').readUInt8(0);
|
||||
}
|
||||
if (coinProfile.testnet) {
|
||||
poolOptions.coin.testnet.bip32.public = Buffer.from(coinProfile.testnet.bip32.public, 'hex').readUInt32LE(0);
|
||||
poolOptions.coin.testnet.pubKeyHash = Buffer.from(coinProfile.testnet.pubKeyHash, 'hex').readUInt8(0);
|
||||
poolOptions.coin.testnet.scriptHash = Buffer.from(coinProfile.testnet.scriptHash, 'hex').readUInt8(0);
|
||||
}
|
||||
|
||||
|
||||
if (poolOptions.coin.name in configs){
|
||||
|
||||
@ -356,7 +371,21 @@ var processCoinSwitchCommand = function(params, options, reply){
|
||||
|
||||
};
|
||||
|
||||
var startSwitchingPaymentProcessor = function(){
|
||||
if (!fs.existsSync('libs/switchingPaymentProcessor.js')) return;
|
||||
|
||||
var worker = cluster.fork({
|
||||
workerType: 'switchingPaymentProcessor',
|
||||
pools: JSON.stringify(poolConfigs),
|
||||
portalConfig: JSON.stringify(portalConfig)
|
||||
});
|
||||
worker.on('exit', function(code, signal){
|
||||
logger.error('Master', 'Switching Payment Processor', 'Died, spawning replacement...');
|
||||
setTimeout(function(){
|
||||
startSwitchingPaymentProcessor();
|
||||
}, 2000);
|
||||
});
|
||||
};
|
||||
|
||||
var startPaymentProcessor = function(){
|
||||
|
||||
@ -434,6 +463,8 @@ var startProfitSwitch = function(){
|
||||
|
||||
startPaymentProcessor();
|
||||
|
||||
startSwitchingPaymentProcessor();
|
||||
|
||||
startWebsite();
|
||||
|
||||
startProfitSwitch();
|
||||
|
||||
@ -15,9 +15,11 @@ module.exports = function(logger, portalConfig, poolConfigs){
|
||||
this.handleApiRequest = function(req, res, next){
|
||||
switch(req.params.method){
|
||||
case 'stats':
|
||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||
res.end(portalStats.statsString);
|
||||
return;
|
||||
case 'pool_stats':
|
||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify(portalStats.statPoolHistory));
|
||||
return;
|
||||
case 'live_stats':
|
||||
|
||||
@ -8,7 +8,7 @@ module.exports = function() {
|
||||
|
||||
// Constants
|
||||
var version = '0.0.1',
|
||||
PUBLIC_API_URL = 'http://www.coinwarz.com/v1/api/profitability/?apikey=YOUR_API_KEY&algo=all',
|
||||
PUBLIC_API_URL = 'https://www.coinwarz.com/v1/api/profitability/?apikey=YOUR_API_KEY&algo=all',
|
||||
USER_AGENT = 'nomp/node-open-mining-portal'
|
||||
|
||||
// Constructor
|
||||
|
||||
@ -8,7 +8,7 @@ module.exports = function() {
|
||||
|
||||
// Constants
|
||||
var version = '0.1.0',
|
||||
PUBLIC_API_URL = 'http://pubapi.cryptsy.com/api.php',
|
||||
PUBLIC_API_URL = 'https://pubapi.cryptsy.com/api.php',
|
||||
PRIVATE_API_URL = 'https://api.cryptsy.com/api',
|
||||
USER_AGENT = 'nomp/node-open-mining-portal'
|
||||
|
||||
|
||||
@ -85,7 +85,7 @@ module.exports = function(logger, poolConfig){
|
||||
shareData.worker,
|
||||
isValidShare ? 'Y' : 'N',
|
||||
isValidBlock ? 'Y' : 'N',
|
||||
shareData.difficulty * (poolConfig.coin.mposDiffMultiplier || 1),
|
||||
shareData.shareDiff,
|
||||
typeof(shareData.error) === 'undefined' ? null : shareData.error,
|
||||
shareData.blockHash ? shareData.blockHash : (shareData.blockHashInvalid ? shareData.blockHashInvalid : '')
|
||||
];
|
||||
|
||||
@ -64,21 +64,35 @@ function SetupForPool(logger, poolOptions, setupFinished){
|
||||
|
||||
async.parallel([
|
||||
function(callback){
|
||||
if (poolOptions.address != false) {
|
||||
daemon.cmd('validateaddress', [poolOptions.address], function(result) {
|
||||
if (result.error){
|
||||
logger.error(logSystem, logComponent, 'Error with payment processing daemon ' + JSON.stringify(result.error));
|
||||
callback(true);
|
||||
}
|
||||
else if (!result.response || !result.response.ismine) {
|
||||
logger.error(logSystem, logComponent,
|
||||
'Daemon does not own pool address - payment processing can not be done with this daemon, '
|
||||
+ JSON.stringify(result.response));
|
||||
callback(true);
|
||||
daemon.cmd('getaddressinfo', [poolOptions.address], function(result) {
|
||||
if (result.error){
|
||||
logger.error(logSystem, logComponent, 'Error with payment processing daemon, getaddressinfo failed ... ' + JSON.stringify(result.error));
|
||||
callback(true);
|
||||
}
|
||||
else if (!result.response || !result.response.ismine) {
|
||||
logger.error(logSystem, logComponent,
|
||||
'Daemon does not own pool address - payment processing can not be done with this daemon, '
|
||||
+ JSON.stringify(result.response));
|
||||
callback(true);
|
||||
}
|
||||
else{
|
||||
callback()
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
else{
|
||||
callback()
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
else callback();
|
||||
},
|
||||
function(callback){
|
||||
daemon.cmd('getbalance', [], function(result){
|
||||
@ -169,7 +183,7 @@ function SetupForPool(logger, poolOptions, setupFinished){
|
||||
|
||||
var workers = {};
|
||||
for (var w in results[0]){
|
||||
workers[w] = {balance: coinsToSatoshies(parseInt(results[0][w]))};
|
||||
workers[w] = {balance: coinsToSatoshies(parseFloat(results[0][w]))};
|
||||
}
|
||||
|
||||
var rounds = results[1].map(function(r){
|
||||
@ -518,12 +532,37 @@ function SetupForPool(logger, poolOptions, setupFinished){
|
||||
});
|
||||
};
|
||||
|
||||
function handleAddress(address) {
|
||||
if (address.length === 40){
|
||||
return util.addressFromEx(poolOptions.address, address);
|
||||
}
|
||||
else return address;
|
||||
}
|
||||
|
||||
var getProperAddress = function(address){
|
||||
if (address.length === 40){
|
||||
return util.addressFromEx(poolOptions.address, address);
|
||||
}
|
||||
else return address;
|
||||
if (address != false) {
|
||||
return handleAddress(address);
|
||||
} else {
|
||||
var addressToPay = '';
|
||||
|
||||
daemon.cmd('getnewaddress', [], function(result){
|
||||
if (result.error){
|
||||
callback(true);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
addressToPay = result.data;
|
||||
}
|
||||
catch(e){
|
||||
logger.error(logSystem, logComponent, 'Error getting a new address. Got: ' + result.data);
|
||||
callback(true);
|
||||
}
|
||||
|
||||
}, true, true);
|
||||
|
||||
return handleAddress(addressToPay);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -18,6 +18,33 @@ module.exports = function(logger){
|
||||
|
||||
var proxySwitch = {};
|
||||
|
||||
var switchingDaemons = (function(){
|
||||
var daemons = {};
|
||||
|
||||
for (var switchName in portalConfig.switching){
|
||||
if (!portalConfig.switching[switchName].singleCoinPayout) continue;
|
||||
var daemonConfig = portalConfig.switching[switchName].singleCoinPayout.daemon;
|
||||
var daemon = new Stratum.daemon.interface([daemonConfig], function(severity, message){
|
||||
logger[severity](logSystem, logComponent, message);
|
||||
});
|
||||
daemons[switchName] = daemon;
|
||||
}
|
||||
|
||||
return daemons;
|
||||
})();
|
||||
|
||||
var singleCoinPayoutPorts = (function(){
|
||||
var ports = {};
|
||||
for (var switchName in portalConfig.switching){
|
||||
if (!portalConfig.switching[switchName].singleCoinPayout) continue;
|
||||
for (var port in portalConfig.switching[switchName].ports){
|
||||
ports[parseInt(port)] = switchName;
|
||||
}
|
||||
}
|
||||
return ports;
|
||||
})();
|
||||
|
||||
|
||||
var redisClient = redis.createClient(portalConfig.redis.port, portalConfig.redis.host);
|
||||
|
||||
//Handle messages from master process sent via IPC
|
||||
@ -128,10 +155,13 @@ module.exports = function(logger){
|
||||
//Functions required for internal payment processing
|
||||
else{
|
||||
|
||||
var shareProcessor = new ShareProcessor(logger, poolOptions);
|
||||
var shareProcessor = new ShareProcessor(logger, portalConfig, poolOptions, singleCoinPayoutPorts);
|
||||
|
||||
handlers.auth = function(port, workerName, password, authCallback){
|
||||
if (poolOptions.validateWorkerUsername !== true)
|
||||
|
||||
var switchDaemon = switchingDaemons[singleCoinPayoutPorts[port]];
|
||||
|
||||
if (!switchDaemon && poolOptions.validateWorkerUsername !== true)
|
||||
authCallback(true);
|
||||
else {
|
||||
if (workerName.length === 40) {
|
||||
@ -144,7 +174,9 @@ module.exports = function(logger){
|
||||
}
|
||||
}
|
||||
else {
|
||||
pool.daemon.cmd('validateaddress', [workerName], function (results) {
|
||||
var daemon = switchDaemon || pool.daemon;
|
||||
|
||||
daemon.cmd('validateaddress', [workerName], function (results) {
|
||||
var isValid = results.filter(function (r) {
|
||||
return r.response.isvalid
|
||||
}).length > 0;
|
||||
@ -184,12 +216,16 @@ module.exports = function(logger){
|
||||
logger.debug(logSystem, logComponent, logSubCat, 'We thought a block was found but it was rejected by the daemon, share data: ' + shareData);
|
||||
|
||||
else if (isValidBlock)
|
||||
logger.debug(logSystem, logComponent, logSubCat, 'Block found: ' + data.blockHash);
|
||||
logger.debug(logSystem, logComponent, logSubCat, 'Block found: ' + data.blockHash + ' by ' + data.worker);
|
||||
|
||||
if (isValidShare)
|
||||
if (isValidShare) {
|
||||
if(data.shareDiff > 1000000000)
|
||||
logger.debug(logSystem, logComponent, logSubCat, 'Share was found with diff higher than 1.000.000.000!');
|
||||
else if(data.shareDiff > 1000000)
|
||||
logger.debug(logSystem, logComponent, logSubCat, 'Share was found with diff higher than 1.000.000!');
|
||||
logger.debug(logSystem, logComponent, logSubCat, 'Share accepted at diff ' + data.difficulty + '/' + data.shareDiff + ' by ' + data.worker + ' [' + data.ip + ']' );
|
||||
|
||||
else if (!isValidShare)
|
||||
} else if (!isValidShare)
|
||||
logger.debug(logSystem, logComponent, logSubCat, 'Share rejected: ' + shareData);
|
||||
|
||||
handlers.share(isValidShare, isValidBlock, data)
|
||||
@ -273,7 +309,7 @@ module.exports = function(logger){
|
||||
if (pools[currentPool])
|
||||
pools[currentPool].getStratumServer().handleNewClient(socket);
|
||||
else
|
||||
pools[initialPool].getStratumServer().handleNewClient(socket);
|
||||
pools[initalPool].getStratumServer().handleNewClient(socket);
|
||||
|
||||
}).listen(parseInt(port), function() {
|
||||
logger.debug(logSystem, logComponent, logSubCat, 'Switching "' + switchName
|
||||
|
||||
@ -15,7 +15,7 @@ value: a hash with..
|
||||
|
||||
|
||||
|
||||
module.exports = function(logger, poolConfig){
|
||||
module.exports = function(logger, portalConfig, poolConfig, singleCoinPayoutPorts){
|
||||
|
||||
var redisConfig = poolConfig.redis;
|
||||
var coin = poolConfig.coin.name;
|
||||
@ -36,7 +36,7 @@ module.exports = function(logger, poolConfig){
|
||||
logger.error(logSystem, logComponent, logSubCat, 'Redis client had an error: ' + JSON.stringify(err))
|
||||
});
|
||||
connection.on('end', function(){
|
||||
logger.error(logSystem, logComponent, logSubCat, 'Connection to redis database as been ended');
|
||||
logger.error(logSystem, logComponent, logSubCat, 'Connection to redis database has been ended');
|
||||
});
|
||||
|
||||
connection.info(function(error, response){
|
||||
@ -68,10 +68,25 @@ module.exports = function(logger, poolConfig){
|
||||
|
||||
this.handleShare = function(isValidShare, isValidBlock, shareData){
|
||||
|
||||
|
||||
/*var shareKey = (function(){
|
||||
var port = shareData.port.toString();
|
||||
for (var switchName in portalConfig.switching){
|
||||
if (!portalConfig.switching[switchName]['singleCoinPayout']) continue;
|
||||
var ports = Object.keys(portalConfig.switching[switchName].ports);
|
||||
if (ports.indexOf(port) !== -1) return switchName;
|
||||
}
|
||||
return coin;
|
||||
})();*/
|
||||
|
||||
var shareKey = singleCoinPayoutPorts[shareData.port] || coin;
|
||||
|
||||
console.log('share key ' + shareKey);
|
||||
|
||||
var redisCommands = [];
|
||||
|
||||
if (isValidShare){
|
||||
redisCommands.push(['hincrbyfloat', coin + ':shares:roundCurrent', shareData.worker, shareData.difficulty]);
|
||||
redisCommands.push(['hincrbyfloat', shareKey + ':shares:roundCurrent', shareData.worker, shareData.difficulty]);
|
||||
redisCommands.push(['hincrby', coin + ':stats', 'validShares', 1]);
|
||||
}
|
||||
else{
|
||||
|
||||
@ -114,7 +114,7 @@ module.exports = function(logger, portalConfig, poolConfigs){
|
||||
['hgetall', ':stats'],
|
||||
['scard', ':blocksPending'],
|
||||
['scard', ':blocksConfirmed'],
|
||||
['scard', ':blocksOrphaned']
|
||||
['scard', ':blocksKicked']
|
||||
];
|
||||
|
||||
var commandsPerCoin = redisCommandTemplates.length;
|
||||
@ -274,9 +274,9 @@ module.exports = function(logger, portalConfig, poolConfigs){
|
||||
var i = -1;
|
||||
var byteUnits = [ ' KH', ' MH', ' GH', ' TH', ' PH' ];
|
||||
do {
|
||||
hashrate = hashrate / 1024;
|
||||
hashrate = hashrate / 1000;
|
||||
i++;
|
||||
} while (hashrate > 1024);
|
||||
} while (hashrate > 1000);
|
||||
return hashrate.toFixed(2) + byteUnits[i];
|
||||
};
|
||||
|
||||
|
||||
12
package.json
12
package.json
@ -31,21 +31,21 @@
|
||||
"url": "https://github.com/zone117x/node-open-mining-portal.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"stratum-pool": "git://github.com/zone117x/node-stratum-pool.git",
|
||||
"dateformat": "*",
|
||||
"stratum-pool": "git://github.com/zone117x/node-stratum-pool.git#dev",
|
||||
"dateformat": "1.0.12",
|
||||
"node-json-minify": "*",
|
||||
"redis": "*",
|
||||
"redis": "0.12.1",
|
||||
"mysql": "*",
|
||||
"async": "*",
|
||||
"async": "1.5.2",
|
||||
"express": "*",
|
||||
"body-parser": "*",
|
||||
"compression": "*",
|
||||
"dot": "*",
|
||||
"colors": "*",
|
||||
"node-watch": "*",
|
||||
"request": "*",
|
||||
"request": "2.69.0",
|
||||
"nonce": "*",
|
||||
"bignum": "*",
|
||||
"bignum": "0.13.0",
|
||||
"extend": "*"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
|
||||
<link rel="icon" type="image/png" href="/static/favicon.png"/>
|
||||
|
||||
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
|
||||
<link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
|
||||
|
||||
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.0.3/css/font-awesome.min.css">
|
||||
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/normalize/3.0.1/normalize.min.css">
|
||||
@ -76,7 +76,7 @@
|
||||
|
||||
<div>
|
||||
This site is powered by the open source <a target="_blank" href="https://github.com/zone117x/node-open-mining-portal/">NOMP</a>
|
||||
project created by Matthew Little and licensed under the <a href="http://www.gnu.org/licenses/gpl-2.0.html">GPL</a>
|
||||
project created by Matthew Little and licensed under the <a href="https://www.gnu.org/licenses/gpl-2.0.html">GPL</a>
|
||||
</div>
|
||||
<div>
|
||||
<i class="fa fa-heart"></i> Support this project by donating <i class="fa fa-btc"></i> BTC: 1KRotMnQpxu3sePQnsVLRy3EraRFYfJQFR
|
||||
@ -84,9 +84,9 @@
|
||||
<div id="communityFooter">
|
||||
Community <i class="fa fa-comment"></i> : <a target="_blank" href="https://kiwiirc.com/client/irc.freenode.net/nomp">#nomp IRC</a>
|
||||
|
|
||||
<a target="_blank" href="http://reddit.com/r/nomp">/r/nomp</a>
|
||||
<a target="_blank" href="https://reddit.com/r/nomp">/r/nomp</a>
|
||||
|
|
||||
<iframe src="http://ghbtns.com/github-btn.html?user=zone117x&repo=node-open-mining-portal&type=watch&count=true" allowtransparency="true" frameborder="0" scrolling="0" width="140" height="20"></iframe>
|
||||
<iframe src="https://ghbtns.com/github-btn.html?user=zone117x&repo=node-open-mining-portal&type=watch&count=true" allowtransparency="true" frameborder="0" scrolling="0" width="140" height="20"></iframe>
|
||||
</div>
|
||||
|
||||
</footer>
|
||||
|
||||
@ -185,9 +185,9 @@
|
||||
<div id="menu">
|
||||
|
||||
{{? (function(){
|
||||
if (!it.portalConfig.proxy) return false;
|
||||
for (var p in it.portalConfig.proxy){
|
||||
if (it.portalConfig.proxy[p].enabled)
|
||||
if (!it.portalConfig.switching) return false;
|
||||
for (var p in it.portalConfig.switching){
|
||||
if (it.portalConfig.switching[p].enabled)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -197,14 +197,14 @@
|
||||
{{?}}
|
||||
|
||||
<div class="menuList">
|
||||
{{ for (var p in it.portalConfig.proxy){
|
||||
if (!it.portalConfig.proxy[p].enabled) continue;
|
||||
{{ for (var p in it.portalConfig.switching){
|
||||
if (!it.portalConfig.switching[p].enabled) continue;
|
||||
var info = {
|
||||
algo: p,
|
||||
ports: {},
|
||||
host: it.portalConfig.website.stratumHost
|
||||
};
|
||||
info.ports[it.portalConfig.proxy[p].port] = {diff: it.portalConfig.proxy[p].diff};
|
||||
info.ports[it.portalConfig.switching[p].port] = {diff: it.portalConfig.switching[p].diff};
|
||||
info = JSON.stringify(info).replace(/"/g, '"');
|
||||
}}
|
||||
<a href="#" class="poolOption" data-info="{{=info}}">{{=p}}</a>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user