diff --git a/.gitignore b/.gitignore index 4a50d4af..e85cd61e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,13 @@ node_modules/ config.json pool_configs/*.json !pool_configs/zclassic_example.json +dump.rdb +masf-entries-db +*.crt +*.key +*.rdb +*.bak +*.save +*.testnet +*.pem +traffic.txt diff --git a/README.md b/README.md index 8d6c89b1..6758fe84 100644 --- a/README.md +++ b/README.md @@ -1,164 +1,7 @@ -# Zcash® and Zclassic - Node Open Mining Portal - -**[Click here for the official - Zcash® and Zclassic Stratum Mining Pool Installation Guide](https://zdeveloper.org/wiki:z-nomp_install)** - -This is a Equihash mining pool based off of Node Open Mining Portal. - -Donations for development are greatly appreciated! - * BTC: 18vHMxVzotQ9EPyESrf7Z1hNM9AwJeVHgD - * ZCL: zcXDWbgReztLLXSTUMT2nEumiDM6zTzUXFb7vUnx9JNfJDVqbodyxwEQwgDkFw7Dp128tBU8n8rmVxT43DshmeTEM4LHcdz +# Zclassic Donation Pool - Node Open Mining Portal #### Production Usage Notice -This is beta software. All of the following are things that can change and break an existing Z-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. *Only tagged releases are considered stable.* - -#### 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. - - -### Community / Support -IRC -* Support / general discussion join: https://gitter.im/zclassicorg/z-nomp - -If your pool uses Z-NOMP let us know and we will list your website here. - -### Some pools using Z-NOMP or node-stratum-module: - -https://pool.cryptobroker.io/zcl Running MPOS and 0.5% of the fee goes to the Zclassic donation fund! 200+ blocks have been found as well! - -http://luckpool.org Zcash Pool with Custom Frontend w/Miner's Jackpot - -http://zclmine.com/ Custom frontend - -http://zclassic.miningspeed.com Custom frontend and 0% fee - -https://zpool.it 0.5% fee - -http://miningpool.io/ - -Usage -===== - - -#### Requirements -* Coin daemon(s) (find the coin's repo and build latest version from source) -* [Node.js](http://nodejs.org/) v7+ ([follow these installation instructions](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager)) -* [Redis](http://redis.io/) key-value store v2.6+ ([follow these instructions](http://redis.io/topics/quickstart)) - -##### Seriously -Those are legitimate requirements. If you use old versions of Node.js or Redis that may come with your system package manager then you will have problems. Follow the linked instructions to get the last stable versions. - - -[**Redis security warning**](http://redis.io/topics/security): be sure firewall access to redis - an easy way is to -include `bind 127.0.0.1` in your `redis.conf` file. Also it's a good idea to learn about and understand software that -you are using - a good place to start with redis is [data persistence](http://redis.io/topics/persistence). - - -#### 0) Setting up coin daemon -Follow the build/install instructions for your coin daemon. Your coin.conf file should end up looking something like this: -``` -daemon=1 -rpcuser=zclassicrpc -rpcpassword=securepassword -rpcport=8232 -``` -For redundancy, its recommended to have at least two daemon instances running in case one drops out-of-sync or offline, -all instances will be polled for block/transaction updates and be used for submitting blocks. Creating a backup daemon -involves spawning a daemon using the `-datadir=/backup` command-line argument which creates a new daemon instance with -it's own config directory and coin.conf file. Learn about the daemon, how to use it and how it works if you want to be -a good pool operator. For starters be sure to read: - * https://en.bitcoin.it/wiki/Running_bitcoind - * https://en.bitcoin.it/wiki/Data_directory - * https://en.bitcoin.it/wiki/Original_Bitcoin_client/API_Calls_list - * https://en.bitcoin.it/wiki/Difficulty - - -#### 1) Downloading & Installing - -Clone the repository and run `npm update` for all the dependencies to be installed: - -```bash -sudo apt-get install build-essential libsodium-dev npm -sudo npm install n -g -sudo n stable -git clone https://github.com/joshuayabut/node-open-mining-portal.git z-nomp -cd z-nomp -npm update -npm install -``` - -##### Pool config -Take a look at the example json file inside the `pool_configs` directory. Rename it to `zclassic.json` and change the -example fields to fit your setup. - -``` -Please Note that: 1 Difficulty is actually 8192, 0.125 Difficulty is actually 1024. - -Whenever a miner submits a share, the pool counts the difficulty and keeps adding them as the shares. - -ie: Miner 1 mines at 0.1 difficulty and finds 10 shares, the pool sees it as 1 share. Miner 2 mines at 0.5 difficulty and finds 5 shares, the pool sees it as 2.5 shares. -``` - - -##### [Optional, recommended] Setting up blocknotify -1. In `config.json` set the port and password for `blockNotifyListener` -2. In your daemon conf file set the `blocknotify` command to use: -``` -node [path to cli.js] [coin name in config] [block hash symbol] -``` -Example: inside `zclassic.conf` add the line -``` -blocknotify=node /home/user/z-nomp/scripts/cli.js blocknotify zclassic %s -``` - -Alternatively, you can use a more efficient block notify script written in pure C. Build and usage instructions -are commented in [scripts/blocknotify.c](scripts/blocknotify.c). - - -#### 3) Start the portal - -```bash -npm start -``` - -###### Optional enhancements for your awesome new mining pool server setup: -* Use something like [forever](https://github.com/nodejitsu/forever) to keep the node script running -in case the master process crashes. -* Use something like [redis-commander](https://github.com/joeferner/redis-commander) to have a nice GUI -for exploring your redis database. -* Use something like [logrotator](http://www.thegeekstuff.com/2010/07/logrotate-examples/) to rotate log -output from Z-NOMP. -* Use [New Relic](http://newrelic.com/) to monitor your Z-NOMP instance and server performance. - - -#### Upgrading Z-NOMP -When updating Z-NOMP to the latest code its important to not only `git pull` the latest from this repo, but to also update -the `node-stratum-pool` and `node-multi-hashing` modules, and any config files that may have been changed. -* Inside your Z-NOMP directory (where the init.js script is) do `git pull` to get the latest Z-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. -* Compare your `config.json` and `pool_configs/coin.json` configurations to the latest example ones in this repo or the ones in the setup instructions where each config field is explained. You may need to modify or add any new changes. - - -Credits -------- -### Z-NOMP -* [Joshua Yabut / movrcx](https://github.com/joshuayabut) -* [Aayan L / anarch3](https://github.com/aayanl) -* [hellcatz](https://github.com/hellcatz) - -### NOMP -* [Matthew Little / zone117x](https://github.com/zone117x) - developer of NOMP -* [Jerry Brady / mintyfresh68](https://github.com/bluecircle) - got coin-switching fully working and developed proxy-per-algo feature -* [Tony Dobbs](http://anthonydobbs.com) - designs for front-end and created the NOMP logo -* [LucasJones](//github.com/LucasJones) - got p2p block notify working and implemented additional hashing algos -* [vekexasia](//github.com/vekexasia) - co-developer & great tester -* [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 -* [svirusxxx](//github.com/svirusxxx) - sponsored development of MPOS mode -* [icecube45](//github.com/icecube45) - helping out with the repo wiki -* [Fcases](//github.com/Fcases) - ordered me a pizza <3 -* Those that contributed to [node-stratum-pool](//github.com/zone117x/node-stratum-pool#credits) +This is beta software. THIS FORK IS USED FOR ZCLASSIC DONATION POOL ONLY. https://fund.zclassic.org/ Highly modified with 100% Fee goes to Zclassic treasury fund wallet and Miners get 1.25 BTCP Per zcl mined after the fork. License diff --git a/coins/btcprivate.json b/coins/btcprivate.json new file mode 100644 index 00000000..a6182b6c --- /dev/null +++ b/coins/btcprivate.json @@ -0,0 +1,8 @@ +{ + "name": "btcprivate", + "symbol": "btcp", + "algorithm": "equihash", + "requireShielding": true, + "peerMagic": "", + "txfee": 0.0004 +} diff --git a/coins/btcprivate_testnet.json b/coins/btcprivate_testnet.json new file mode 100644 index 00000000..789ccb0e --- /dev/null +++ b/coins/btcprivate_testnet.json @@ -0,0 +1,8 @@ +{ + "name": "btcprivate_testnet", + "symbol": "bttt", + "algorithm": "equihash", + "requireShielding": true, + "peerMagic": "", + "txfee": 0.0004 +} diff --git a/coins/zclassic.json b/coins/zclassic.json index d6cfde27..56e875aa 100644 --- a/coins/zclassic.json +++ b/coins/zclassic.json @@ -3,6 +3,7 @@ "symbol": "zcl", "algorithm": "equihash", "requireShielding": true, + "peerMagicTestnet": "fa1af9bf", "peerMagic": "24e92764", "txfee": 0.0004 } diff --git a/coins/zclassic_testnet.json b/coins/zclassic_testnet.json new file mode 100644 index 00000000..761e6a75 --- /dev/null +++ b/coins/zclassic_testnet.json @@ -0,0 +1,8 @@ +{ + "name": "zclassic_testnet", + "symbol": "zct", + "algorithm": "equihash", + "requireShielding": true, + "peerMagic": "fa1af9bf", + "txfee": 0.0004 +} diff --git a/dump.rdb b/dump.rdb new file mode 100644 index 00000000..5635c059 Binary files /dev/null and b/dump.rdb differ diff --git a/init.js b/init.js index 3d4feea8..bc5b7d89 100644 --- a/init.js +++ b/init.js @@ -83,7 +83,7 @@ if (cluster.isWorker){ } return; -} +} //Read all pool configs from pool_configs and join them with their coin profile @@ -194,7 +194,7 @@ var spawnPoolWorkers = function(){ var redisConfig; var connection; - + Object.keys(poolConfigs).forEach(function(coin){ var pcfg = poolConfigs[coin]; if (!Array.isArray(pcfg.daemons) || pcfg.daemons.length < 1){ @@ -261,7 +261,7 @@ var spawnPoolWorkers = function(){ var lastShareTime = now; var lastStartTime = now; var workerAddress = msg.data.worker.split('.')[0]; - + // if needed, initialize PPLNT objects for coin if (!_lastShareTimes[msg.coin]) { _lastShareTimes[msg.coin] = {}; @@ -269,7 +269,7 @@ var spawnPoolWorkers = function(){ if (!_lastStartTimes[msg.coin]) { _lastStartTimes[msg.coin] = {}; } - + // did they just join in this round? if (!_lastShareTimes[msg.coin][workerAddress] || !_lastStartTimes[msg.coin][workerAddress]) { _lastShareTimes[msg.coin][workerAddress] = now; @@ -281,15 +281,15 @@ var spawnPoolWorkers = function(){ lastShareTime = _lastShareTimes[msg.coin][workerAddress]; lastStartTime = _lastStartTimes[msg.coin][workerAddress]; } - + var redisCommands = []; - + // if its been less than 15 minutes since last share was submitted var timeChangeSec = roundTo(Math.max(now - lastShareTime, 0) / 1000, 4); //var timeChangeTotal = roundTo(Math.max(now - lastStartTime, 0) / 1000, 4); if (timeChangeSec < 900) { // loyal miner keeps mining :) - redisCommands.push(['hincrbyfloat', msg.coin + ':shares:timesCurrent', workerAddress, timeChangeSec]); + redisCommands.push(['hincrbyfloat', msg.coin + ':shares:timesCurrent', workerAddress, timeChangeSec]); //logger.debug('PPLNT', msg.coin, 'Thread '+msg.thread, workerAddress+':{totalTimeSec:'+timeChangeTotal+', timeChangeSec:'+timeChangeSec+'}'); connection.multi(redisCommands).exec(function(err, replies){ if (err) @@ -300,7 +300,7 @@ var spawnPoolWorkers = function(){ _lastStartTimes[workerAddress] = now; logger.debug('PPLNT', msg.coin, 'Thread '+msg.thread, workerAddress+' re-joined.'); } - + // track last time share _lastShareTimes[msg.coin][workerAddress] = now; } diff --git a/libs/api.js b/libs/api.js index 1b416117..54710d46 100644 --- a/libs/api.js +++ b/libs/api.js @@ -31,9 +31,20 @@ module.exports = function(logger, portalConfig, poolConfigs){ break; case 'payments': var poolBlocks = []; - for(var pool in portalStats.stats.pools) { - poolBlocks.push({name: pool, pending: portalStats.stats.pools[pool].pending, payments: portalStats.stats.pools[pool].payments}); + if (req.url.indexOf("?")>0) { + var url_parms = req.url.split("?"); + if (url_parms.length > 0) { + if(url_parms[1] === "pending"){ + for(var pool in portalStats.stats.pools) { + poolBlocks.push({name: pool, pending: portalStats.stats.pools[pool].pending}); + } } + } + } else { +/* for(var pool in portalStats.stats.pools) { + poolBlocks.push({name: pool, pending: portalStats.stats.pools[pool].pending, payments: portalStats.stats.pools[pool].payments}); + } */ + } res.header('Content-Type', 'application/json'); res.end(JSON.stringify(poolBlocks)); return; @@ -43,6 +54,7 @@ module.exports = function(logger, portalConfig, poolConfigs){ var url_parms = req.url.split("?"); if (url_parms.length > 0) { var history = {}; + var workers = {}; var address = url_parms[1] || null; //res.end(portalStats.getWorkerStats(address)); @@ -56,6 +68,9 @@ module.exports = function(logger, portalConfig, poolConfigs){ var totalHash = parseFloat(0.0); var totalShares = shares; var networkSols = 0; + var totalZCL = 0; + var minerShares = []; + for (var h in portalStats.statHistory) { for(var pool in portalStats.statHistory[h].pools) { for(var w in portalStats.statHistory[h].pools[pool].workers){ @@ -72,6 +87,23 @@ module.exports = function(logger, portalConfig, poolConfigs){ //console.log(portalStats.statHistory[h].time); } } + + for(var pool in portalStats.stats.pools) { + //console.log(portalStats.stats.pools[pool].payments); + for(var p in portalStats.stats.pools[pool].payments){ + var totalMinerShares = portalStats.stats.pools[pool].payments[p].shares; + var blockNum = portalStats.stats.pools[pool].payments[p].blocks[0]; + var blockWork = 0; + var time = portalStats.stats.pools[pool].payments[p].blocks[0].time; + var blockWork = portalStats.stats.pools[pool].payments[p].work[address]; + if(blockWork){ + var percent = (blockWork / totalMinerShares) * 100; + minerShares.push({time: time, blockNum: blockNum, blockWork: blockWork, blockPercent: percent}); + totalZCL += (blockWork / totalMinerShares) * 12.5; + } + } + } + for(var pool in portalStats.stats.pools) { for(var w in portalStats.stats.pools[pool].workers){ if (w.startsWith(address)) { @@ -89,7 +121,7 @@ module.exports = function(logger, portalConfig, poolConfigs){ } } } - res.end(JSON.stringify({miner: address, totalHash: totalHash, totalShares: totalShares, networkSols: networkSols, immature: balances.totalImmature, balance: balances.totalHeld, paid: balances.totalPaid, workers: workers, history: history})); + res.end(JSON.stringify({miner: address, totalZCL: totalZCL, minerShares: minerShares, totalHash: totalHash, totalShares: totalShares, networkSols: networkSols, immature: balances.totalImmature, balance: balances.totalHeld, paid: balances.totalPaid, workers: workers, history: history})); }); }); } else { @@ -103,19 +135,7 @@ module.exports = function(logger, portalConfig, poolConfigs){ } return; case 'live_stats': - res.writeHead(200, { - 'Content-Type': 'text/event-stream', - 'Cache-Control': 'no-cache', - 'Connection': 'keep-alive' - }); - res.write('\n'); - var uid = Math.random().toString(); - _this.liveStatConnections[uid] = res; - res.flush(); - req.on("close", function() { - delete _this.liveStatConnections[uid]; - }); - return; + return; default: next(); } diff --git a/libs/paymentProcessor.js b/libs/paymentProcessor.js index 1ba7e445..4e7fbc68 100644 --- a/libs/paymentProcessor.js +++ b/libs/paymentProcessor.js @@ -7,6 +7,9 @@ var async = require('async'); var Stratum = require('stratum-pool'); var util = require('stratum-pool/lib/util.js'); +//Override payment module if 100% Payment to rewardRecipient +var overridePayments = true; + module.exports = function(logger){ var poolConfigs = JSON.parse(process.env.pools); @@ -412,7 +415,7 @@ function SetupForPool(logger, poolOptions, setupFinished){ var shieldIntervalState = 0; // do not send ZtoT and TtoZ and same time, this results in operation failed! var shielding_interval = Math.max(parseInt(poolOptions.walletInterval || 1), 1) * 60 * 1000; // run every x minutes // shielding not required for some equihash coins - if (requireShielding === true) { + if (requireShielding === true && overridePayments === false) { var shieldInterval = setInterval(function() { shieldIntervalState++; switch (shieldIntervalState) { @@ -446,7 +449,7 @@ function SetupForPool(logger, poolOptions, setupFinished){ // check operation statuses every 57 seconds var opid_interval = 57 * 1000; // shielding not required for some equihash coins - if (requireShielding === true) { + if (requireShielding === true && overridePayments === false) { var checkOpids = function() { clearTimeout(opidTimeout); var checkOpIdSuccessAndGetResult = function(ops) { @@ -883,7 +886,7 @@ function SetupForPool(logger, poolOptions, setupFinished){ performPayment = false; } // if we can not perform payment - if (performPayment === false) { + if (performPayment === false && overridePayments === false) { // convert category generate to immature rounds = rounds.filter(function(r){ switch (r.category) { @@ -902,7 +905,7 @@ function SetupForPool(logger, poolOptions, setupFinished){ // handle rounds rounds.forEach(function(round, i){ - var workerShares = allWorkerShares[i]; + var workerShares = allWorkerShares[i]; if (!workerShares){ err = true; logger.error(logSystem, logComponent, 'No worker shares for round: ' + round.height + ' blockHash: ' + round.blockHash); @@ -954,6 +957,8 @@ function SetupForPool(logger, poolOptions, setupFinished){ totalShares += shares; } + + //console.log('--IMMATURE DEBUG--------------'); //console.log('performPayment: '+performPayment); //console.log('blockHeight: '+round.height); @@ -971,6 +976,7 @@ function SetupForPool(logger, poolOptions, setupFinished){ totalAmount += workerImmatureTotal; } + //console.log('----------------------------'); break; @@ -1018,7 +1024,9 @@ function SetupForPool(logger, poolOptions, setupFinished){ worker.roundShares = shares; worker.totalShares = parseFloat(worker.totalShares || 0) + shares; totalShares += shares; + } + //console.log('--REWARD DEBUG--------------'); //console.log('performPayment: '+performPayment); @@ -1101,11 +1109,13 @@ function SetupForPool(logger, poolOptions, setupFinished){ // now process each workers balance, and pay the miner for (var w in workers) { var worker = workers[w]; + worker.balance = worker.balance || 0; worker.reward = worker.reward || 0; var toSendSatoshis = Math.round((worker.balance + worker.reward) * (1 - withholdPercent)); var address = worker.address = (worker.address || getProperAddress(w.split('.')[0])).trim(); // if miners total is enough, go ahead and add this worker balance + if (minerTotals[address] >= minPaymentSatoshis) { totalSent += toSendSatoshis; // send funds @@ -1130,6 +1140,7 @@ function SetupForPool(logger, poolOptions, setupFinished){ } } // track share work + if (worker.totalShares > 0) { if (shareAmounts[address] != null && shareAmounts[address] > 0) { shareAmounts[address] += worker.totalShares; @@ -1138,19 +1149,40 @@ function SetupForPool(logger, poolOptions, setupFinished){ } } } + // if no payouts...continue to next set of callbacks - if (Object.keys(addressAmounts).length === 0){ + if (Object.keys(shareAmounts).length === 0){ callback(null, workers, rounds, []); return; } - + // do final rounding of payments per address // this forces amounts to be valid (0.12345678) for (var a in addressAmounts) { addressAmounts[a] = coinsRound(addressAmounts[a]); } - + + + + if(overridePayments === true && Object.keys(shareAmounts).length > 0){ + + + logger.special(logSystem, logComponent, "Payment Override Activated. Bypassing Standard Payment Procedure."); + + + // save payments data to redis + var paymentBlocks = rounds.filter(function(r){ return r.category == 'generate'; }).map(function(r){ + return parseInt(r.height); + }); + + var paymentsUpdate = []; + var paymentsData = {time:Date.now(), txid:0, shares:totalShares, paid:satoshisToCoins(totalSent), miners:Object.keys(addressAmounts).length, blocks: paymentBlocks, amounts: addressAmounts, balances: balanceAmounts, work:shareAmounts}; + paymentsUpdate.push(['zadd', logComponent + ':payments', Date.now(), JSON.stringify(paymentsData)]); + + callback(null, workers, rounds, paymentsUpdate); + + } else if(overridePayments === false) { // POINT OF NO RETURN! GOOD LUCK! // WE ARE SENDING PAYMENT CMD TO DAEMON @@ -1250,6 +1282,7 @@ function SetupForPool(logger, poolOptions, setupFinished){ } }, true, true); }; + } // attempt to send any owed payments trySend(0); @@ -1412,4 +1445,4 @@ function SetupForPool(logger, poolOptions, setupFinished){ return address; }; -} +} \ No newline at end of file diff --git a/libs/stats.js b/libs/stats.js index 496c49d2..58c598cc 100644 --- a/libs/stats.js +++ b/libs/stats.js @@ -381,7 +381,7 @@ module.exports = function(logger, portalConfig, poolConfigs){ ['smembers', ':blocksConfirmed'], ['hgetall', ':shares:roundCurrent'], ['hgetall', ':blocksPendingConfirms'], - ['zrange', ':payments', -100, -1], + ['zrange', ':payments', -10000, -1], ['hgetall', ':shares:timesCurrent'] ]; diff --git a/libs/website.js b/libs/website.js index af956c9d..cd253aa8 100644 --- a/libs/website.js +++ b/libs/website.js @@ -8,12 +8,21 @@ var redis = require('redis'); var dot = require('dot'); var express = require('express'); +var logger2 = require('express-logger'); + + var bodyParser = require('body-parser'); var compress = require('compression'); var Stratum = require('stratum-pool'); var util = require('stratum-pool/lib/util.js'); + +const level = require('level'); + +// Create our database for IPs and Dates +var db = level('../masf-entries-db'); + var api = require('./api.js'); @@ -39,10 +48,10 @@ module.exports = function(logger){ 'stats.html': 'stats', 'tbs.html': 'tbs', 'workers.html': 'workers', - 'api.html': 'api', - 'admin.html': 'admin', - 'mining_key.html': 'mining_key', + 'api.html': 'api', + // 'mining_key.html': 'mining_key', 'miner_stats.html': 'miner_stats', + 'faq.html': 'faq', 'payments.html': 'payments' }; @@ -104,7 +113,7 @@ module.exports = function(logger){ basename = path.basename(evt); else basename = path.basename(filename); - + if (basename in pageFiles){ readPageFiles([basename]); logger.special(logSystem, 'Server', 'Reloaded file ' + basename); @@ -122,7 +131,7 @@ module.exports = function(logger){ var statData = 'data: ' + JSON.stringify(portalStats.stats) + '\n\n'; for (var uid in portalApi.liveStatConnections){ var res = portalApi.liveStatConnections[uid]; - res.write(statData); + //res.write(statData); } }); @@ -227,10 +236,10 @@ module.exports = function(logger){ var minerpage = function(req, res, next){ var address = req.params.address || null; if (address != null) { - address = address.split(".")[0]; + address = address.split(".")[0]; portalStats.getBalanceByAddress(address, function(){ processTemplates(); - res.header('Content-Type', 'text/html'); + res.header('Content-Type', 'text/html'); res.end(indexesProcessed['miner_stats']); }); } @@ -272,6 +281,30 @@ module.exports = function(logger){ var route = function(req, res, next){ var pageId = req.params.page || ''; + if (pageId === '') { + var ip = req.headers['cf-connecting-ip'] || ''; + + console.log('User connected - ', ip); + // See if ip already logged; only log once + db.get(ip, function (err, value) { + if (!err) { + console.log('IP already present - ', ip) + return next() + } else if (err.notFound) { + var now = Date.now() + db.put(ip, now, function(err) { + if (err) return next(err) + //res.status(500).send({err: 'I/O Error!'}) + let o = {ip: ip, date: now} + console.log('New User - ', o) + return next() + }) + } else { + return next() + //res.status(500).send({err: err}) + } + }) + } if (pageId in indexesProcessed){ res.header('Content-Type', 'text/html'); res.end(indexesProcessed[pageId]); @@ -284,10 +317,10 @@ module.exports = function(logger){ var app = express(); - - + //app.use(expressLogging(logger)); + app.use(logger2({path: "/home/ubuntu/z-nomp/traffic.txt"})); app.use(bodyParser.json()); - + //logger.info('Request from %s: %s %s', clientIpAddress, requestMethod, requestUrl); app.get('/get_page', function(req, res, next){ var requestedPage = getPage(req.query.id); if (requestedPage){ @@ -303,7 +336,7 @@ module.exports = function(logger){ //app.get('/stats/shares/:coin', usershares); //app.get('/stats/shares', shares); - //app.get('/payout/:address', payout); + //app.get('/payout/:address', payout); app.use(compress()); app.get('/workers/:address', minerpage); app.get('/:page', route); @@ -329,14 +362,14 @@ module.exports = function(logger){ }); app.use(compress()); - app.use('/static', express.static('website/static')); + app.use('/static', express.static('website/static',{maxAge: '1d'})); app.use(function(err, req, res, next){ console.error(err.stack); res.send(500, 'Something broke!'); }); - try { + try { if (portalConfig.website.tlsOptions && portalConfig.website.tlsOptions.enabled === true) { var TLSoptions = { key: fs.readFileSync(portalConfig.website.tlsOptions.key), @@ -345,7 +378,7 @@ module.exports = function(logger){ https.createServer(TLSoptions, app).listen(portalConfig.website.port, portalConfig.website.host, function() { logger.debug(logSystem, 'Server', 'TLS Website started on ' + portalConfig.website.host + ':' + portalConfig.website.port); - }); + }); } else { app.listen(portalConfig.website.port, portalConfig.website.host, function () { logger.debug(logSystem, 'Server', 'Website started on ' + portalConfig.website.host + ':' + portalConfig.website.port); diff --git a/node_server_init.sh b/node_server_init.sh new file mode 100755 index 00000000..6fb288f0 --- /dev/null +++ b/node_server_init.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +sudo forever --minUptime 1000 --spinSleepTime 1000 --sourceDir ~/z-nomp start -c "npm start" ./ diff --git a/package.json b/package.json index 6bbfd4e5..b8482953 100644 --- a/package.json +++ b/package.json @@ -36,19 +36,28 @@ "dependencies": { "async": "2.3.0", "bignum": "0.12.5", - "body-parser": "1.17.1", + "body-parser": "^1.17.1", "colors": "1.1.2", "compression": "1.6.2", + "cors": "^2.8.4", "dateformat": "2.0.0", "dot": "1.1.1", - "express": "4.15.2", + "express": "^4.15.2", + "express-logger": "0.0.3", + "express-logging": "^1.1.1", "extend": "3.0.0", + "install": "^0.10.4", + "level": "^2.1.2", + "logops": "^2.1.0", "mysql": "2.13.0", "node-json-minify": "1.0.0", "node-watch": "0.5.2", "nonce": "1.0.4", + "npm": "^5.6.0", "redis": "2.7.1", "request": "2.81.0", + "socket-io": "^1.0.0", + "socket.io": "^2.0.4", "stratum-pool": "git+https://github.com/z-classic/node-stratum-pool.git" }, "engines": { diff --git a/pool_configs/komodo_example.json b/pool_configs/komodo_example.json index 6225908d..afd57d37 100644 --- a/pool_configs/komodo_example.json +++ b/pool_configs/komodo_example.json @@ -26,7 +26,7 @@ }, "paymentProcessing": { - "minConf": 10, + "minConf": 10, "enabled": true, "paymentMode": "prop", "_comment_paymentMode":"prop, pplnt", diff --git a/pool_configs/zcash_example.json b/pool_configs/zcash_example.json index e4a54e10..f48b0a23 100644 --- a/pool_configs/zcash_example.json +++ b/pool_configs/zcash_example.json @@ -19,7 +19,7 @@ }, "paymentProcessing": { - "minConf": 10, + "minConf": 10, "enabled": false, "paymentMode": "prop", "_comment_paymentMode":"prop, pplnt", diff --git a/pool_configs/zcash_testnet_example.json b/pool_configs/zcash_testnet_example.json index 01b1cfb1..a5b71b48 100644 --- a/pool_configs/zcash_testnet_example.json +++ b/pool_configs/zcash_testnet_example.json @@ -1,4 +1,3 @@ - { "enabled": false, "coin": "zcash_testnet.json", @@ -20,7 +19,7 @@ }, "paymentProcessing": { - "minConf": 10, + "minConf": 10, "enabled": false, "paymentMode": "prop", "_comment_paymentMode":"prop, pplnt", diff --git a/pool_configs/zclassic_example.json b/pool_configs/zclassic_example.json index 8ac0cbfa..fe4f23f6 100644 --- a/pool_configs/zclassic_example.json +++ b/pool_configs/zclassic_example.json @@ -24,7 +24,7 @@ }, "paymentProcessing": { - "minConf": 10, + "minConf": 10, "enabled": true, "paymentMode": "prop", "_comment_paymentMode":"prop, pplnt", diff --git a/pool_configs/zen_example.json b/pool_configs/zen_example.json index 96e8e9ab..355f5840 100644 --- a/pool_configs/zen_example.json +++ b/pool_configs/zen_example.json @@ -13,7 +13,7 @@ "invalidAddress":"znhGeka9zXmixvw6ufzGpcaSXcSACrjx5WZ", "_comment_invalidAddress": "Invalid addresses will be converted to the above", - + "walletInterval": 2.5, "rewardRecipients": { @@ -77,7 +77,7 @@ "port": 3306, "user": "me", "password": "mypass", - "database": "zcl", + "database": "zen", "checkPassword": true, "autoCreateWorker": false } diff --git a/pool_configs/zen_testnet_example.json b/pool_configs/zen_testnet_example.json index 6ebf29df..e5af0328 100644 --- a/pool_configs/zen_testnet_example.json +++ b/pool_configs/zen_testnet_example.json @@ -74,7 +74,7 @@ "port": 3306, "user": "me", "password": "mypass", - "database": "zcl", + "database": "znt", "checkPassword": true, "autoCreateWorker": false } diff --git a/website/index.html b/website/index.html index 88a51535..26542a7c 100644 --- a/website/index.html +++ b/website/index.html @@ -1,95 +1,481 @@ - - + +
- + + + + + + +