From b08468ba8d25ad31bd1bc3c90f1ba3a267022062 Mon Sep 17 00:00:00 2001 From: Matt Date: Wed, 2 Apr 2014 13:01:05 -0600 Subject: [PATCH 1/4] Added "emitInvalidBlocksHahes" option for those in MPOS mode that require it. --- .gitignore | 3 +- README.md | 3 ++ coins/365coin.json | 5 ++++ config_example.json | 61 +++++++++++++++++++++++++++++++++++++++ libs/mposCompatibility.js | 2 +- libs/paymentProcessor.js | 13 +++++---- libs/poolWorker.js | 6 ++-- libs/shareProcessor.js | 4 +-- 8 files changed, 84 insertions(+), 13 deletions(-) create mode 100644 coins/365coin.json create mode 100644 config_example.json diff --git a/.gitignore b/.gitignore index d35bbf7..88d9a09 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules/ -.idea/ \ No newline at end of file +.idea/ +config.json \ No newline at end of file diff --git a/README.md b/README.md index 66f9f49..de2b6cd 100644 --- a/README.md +++ b/README.md @@ -267,6 +267,9 @@ Description of options: detects those and disconnects them. */ "connectionTimeout": 600, //Remove workers that haven't been in contact for this many seconds + /* Sometimes you want the block hashes even for shares that aren't block candidates. */ + "emitInvalidBlockHashes": false, + /* 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. */ "banning": { diff --git a/coins/365coin.json b/coins/365coin.json new file mode 100644 index 0000000..c208e44 --- /dev/null +++ b/coins/365coin.json @@ -0,0 +1,5 @@ +{ + "name": "365coin", + "symbol": "365", + "algorithm": "keccak" +} \ No newline at end of file diff --git a/config_example.json b/config_example.json new file mode 100644 index 0000000..b0fa531 --- /dev/null +++ b/config_example.json @@ -0,0 +1,61 @@ +{ + "logLevel": "debug", + "clustering": { + "enabled": true, + "forks": "auto" + }, + "blockNotifyListener": { + "enabled": false, + "port": 8117, + "password": "test" + }, + + "redisBlockNotifyListener": { + "enabled" : false, + "redisPort" : 6379, + "redisHost" : "hostname", + "psubscribeKey" : "newblocks:*" + }, + "website": { + "enabled": true, + "siteTitle": "Cryppit", + "port": 80, + "statUpdateInterval": 1.5, + "hashrateWindow": 300 + }, + "proxy": { + "enabled": false, + "ports": { + "80": { + "diff": 32, + "varDiff": { + "minDiff" : 8, + "maxDiff" : 512, + "targetTime" : 15, + "retargetTime" : 90, + "variancePercent" : 30 + } + }, + "6000": { + "diff": 32, + "varDiff": { + "minDiff" : 8, + "maxDiff" : 512, + "targetTime" : 15, + "retargetTime" : 90, + "variancePercent" : 30 + } + }, + "8080": { + "diff": 32, + "varDiff": { + "minDiff" : 8, + "maxDiff" : 512, + "targetTime" : 15, + "retargetTime" : 90, + "variancePercent" : 30 + } + } + } + } +} \ No newline at end of file diff --git a/libs/mposCompatibility.js b/libs/mposCompatibility.js index 4b75adb..26b30a2 100644 --- a/libs/mposCompatibility.js +++ b/libs/mposCompatibility.js @@ -70,7 +70,7 @@ module.exports = function(logger, poolConfig){ isValidBlock ? 'Y' : 'N', shareData.difficulty, typeof(shareData.error) === 'undefined' ? null : shareData.error, - typeof(shareData.solution) === 'undefined' ? '' : shareData.solution + shareData.blockHash ? shareData.blockHash : (shareData.blockHashInvalid ? shareData.blockHashInvalid : '') ]; connection.query( 'INSERT INTO `shares` SET time = NOW(), rem_host = ?, username = ?, our_result = ?, upstream_result = ?, difficulty = ?, reason = ?, solution = ?', diff --git a/libs/paymentProcessor.js b/libs/paymentProcessor.js index a9edd14..11ddc7f 100644 --- a/libs/paymentProcessor.js +++ b/libs/paymentProcessor.js @@ -160,7 +160,7 @@ function SetupForPool(logger, poolOptions, setupFinished){ var details = r.split(':'); return { category: details[0].category, - solution: details[0], + blockHash: details[0], txHash: details[1], height: details[2], reward: details[3], @@ -191,20 +191,20 @@ function SetupForPool(logger, poolOptions, setupFinished){ txDetails.forEach(function(tx, i){ var round = rounds[i]; - if (tx.error && tx.error.code === -5 || round.solution !== tx.result.blockhash){ + if (tx.error && tx.error.code === -5 || round.blockHash !== tx.result.blockhash){ /* Block was dropped from coin daemon even after it happily accepted it earlier. */ //If we find another block at the same height then this block was drop-kicked orphaned var dropKicked = rounds.filter(function(r){ - return r.height === round.height && r.solution !== round.solution && r.category !== 'dropkicked'; + return r.height === round.height && r.blockHash !== round.blockHash && r.category !== 'dropkicked'; }).length > 0; if (dropKicked){ logger.warning(logSystem, logComponent, 'A block was drop-kicked orphaned' - + ' - we found a better block at the same height, solution ' - + round.solution + " round " + round.height); + + ' - we found a better block at the same height, blockHash ' + + round.blockHash + " round " + round.height); round.category = 'dropkicked'; } else{ @@ -298,7 +298,7 @@ function SetupForPool(logger, poolOptions, setupFinished){ if (!workerShares){ logger.error(logSystem, logComponent, 'No worker shares for round: ' - + round.height + ' solution: ' + round.solution); + + round.height + ' blockHash: ' + round.blockHash); return; } @@ -486,6 +486,7 @@ function SetupForPool(logger, poolOptions, setupFinished){ if (toBePaid !== 0) finalRedisCommands.push(['hincrbyfloat', coin + '_stats', 'totalPaid', (toBePaid / magnitude).toFixed(coinPrecision)]); + finalRedisCommands.push(['bgsave']); callback(null, magnitude, workerPayments, finalRedisCommands); diff --git a/libs/poolWorker.js b/libs/poolWorker.js index fdcde2f..453ea08 100644 --- a/libs/poolWorker.js +++ b/libs/poolWorker.js @@ -118,11 +118,11 @@ module.exports = function(logger){ var shareData = JSON.stringify(data); - if (data.solution && !isValidBlock) - logger.debug(logSystem, logComponent, logSubCat, 'We thought a block solution was found but it was rejected by the daemon, share data: ' + shareData); + if (data.blockHash && !isValidBlock) + 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 solution found: ' + data.solution); + logger.debug(logSystem, logComponent, logSubCat, 'Block found: ' + data.blockHash); if (isValidShare) diff --git a/libs/shareProcessor.js b/libs/shareProcessor.js index 938bd48..57df98e 100644 --- a/libs/shareProcessor.js +++ b/libs/shareProcessor.js @@ -61,10 +61,10 @@ module.exports = function(logger, poolConfig){ if (isValidBlock){ redisCommands.push(['rename', coin + '_shares:roundCurrent', coin + '_shares:round' + shareData.height]); - redisCommands.push(['sadd', coin + '_blocksPending', [shareData.solution, shareData.tx, shareData.height, shareData.reward].join(':')]); + redisCommands.push(['sadd', coin + '_blocksPending', [shareData.blockHash, shareData.txHash, shareData.height, shareData.reward].join(':')]); redisCommands.push(['hincrby', coin + '_stats', 'validBlocks', 1]); } - else if (shareData.solution){ + else if (shareData.blockHash){ redisCommands.push(['hincrby', coin + '_stats', 'invalidBlocks', 1]); } From 4904f050f5e6e56087acf6df91eba05916a3f9ab Mon Sep 17 00:00:00 2001 From: Matthew Little Date: Wed, 2 Apr 2014 13:02:11 -0600 Subject: [PATCH 2/4] Delete config.json --- config.json | 61 ----------------------------------------------------- 1 file changed, 61 deletions(-) delete mode 100644 config.json diff --git a/config.json b/config.json deleted file mode 100644 index b0fa531..0000000 --- a/config.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "logLevel": "debug", - "clustering": { - "enabled": true, - "forks": "auto" - }, - "blockNotifyListener": { - "enabled": false, - "port": 8117, - "password": "test" - }, - - "redisBlockNotifyListener": { - "enabled" : false, - "redisPort" : 6379, - "redisHost" : "hostname", - "psubscribeKey" : "newblocks:*" - }, - "website": { - "enabled": true, - "siteTitle": "Cryppit", - "port": 80, - "statUpdateInterval": 1.5, - "hashrateWindow": 300 - }, - "proxy": { - "enabled": false, - "ports": { - "80": { - "diff": 32, - "varDiff": { - "minDiff" : 8, - "maxDiff" : 512, - "targetTime" : 15, - "retargetTime" : 90, - "variancePercent" : 30 - } - }, - "6000": { - "diff": 32, - "varDiff": { - "minDiff" : 8, - "maxDiff" : 512, - "targetTime" : 15, - "retargetTime" : 90, - "variancePercent" : 30 - } - }, - "8080": { - "diff": 32, - "varDiff": { - "minDiff" : 8, - "maxDiff" : 512, - "targetTime" : 15, - "retargetTime" : 90, - "variancePercent" : 30 - } - } - } - } -} \ No newline at end of file From 53283f502289f23c597b995342ff5c842932688a Mon Sep 17 00:00:00 2001 From: Matthew Little Date: Wed, 2 Apr 2014 13:06:06 -0600 Subject: [PATCH 3/4] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index de2b6cd..75c9990 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ npm update #### 2) Configuration ##### Portal config -Inside the `config.json` file, ensure the default configuration will work for your environment. +Inside the `config_example.json` file, ensure the default configuration will work for your environment, then copy the file to `config.json`. Explanation for each field: ````javascript @@ -232,7 +232,9 @@ Description of options: } }, - "mpos": { //Enabled this and shares will be inserted into share table in a MySQL database + /* Enabled mpos and shares will be inserted into share table in a MySQL database. You may + also want to use the "emitInvalidBlockHashes" option below if you require it. */ + "mpos": { "enabled": false, "host": "localhost", //MySQL db host "port": 3306, //MySQL db port From db99f49ec05857e3c814d63f7988216ca0753b80 Mon Sep 17 00:00:00 2001 From: Matt Date: Wed, 2 Apr 2014 14:09:57 -0600 Subject: [PATCH 4/4] Added unsupported algorithm error and fixed algo for helixcoin --- coins/helixcoin.json | 2 +- init.js | 25 +++++++++++++++++-------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/coins/helixcoin.json b/coins/helixcoin.json index 9fc6f85..65302ec 100644 --- a/coins/helixcoin.json +++ b/coins/helixcoin.json @@ -1,5 +1,5 @@ { "name": "Helixcoin", "symbol": "HXC", - "algorithm": "max" + "algorithm": "keccak" } \ No newline at end of file diff --git a/init.js b/init.js index 982b358..decf2cb 100644 --- a/init.js +++ b/init.js @@ -3,15 +3,18 @@ var path = require('path'); var os = require('os'); var cluster = require('cluster'); -var async = require('async'); -var posix = require('posix'); -var PoolLogger = require('./libs/logUtil.js'); -var BlocknotifyListener = require('./libs/blocknotifyListener.js'); +var async = require('async'); +var posix = require('posix'); +var PoolLogger = require('./libs/logUtil.js'); +var BlocknotifyListener = require('./libs/blocknotifyListener.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'); +var WorkerListener = require('./libs/workerListener.js'); +var PoolWorker = require('./libs/poolWorker.js'); +var PaymentProcessor = require('./libs/paymentProcessor.js'); +var Website = require('./libs/website.js'); + +var algos = require('stratum-pool/lib/algoProperties.js'); + JSON.minify = JSON.minify || require("node-json-minify"); var portalConfig = JSON.parse(JSON.minify(fs.readFileSync("config.json", {encoding: 'utf8'}))); @@ -88,6 +91,12 @@ var buildPoolConfigs = function(){ var coinProfile = JSON.parse(JSON.minify(fs.readFileSync(coinFilePath, {encoding: 'utf8'}))); poolOptions.coin = coinProfile; configs[poolOptions.coin.name] = poolOptions; + + if (!(coinProfile.algorithm in algos)){ + logger.error('Master', coinProfile.name, 'Cannot run a pool for unsupported algorithm "' + coinProfile.algorithm + '"'); + delete configs[poolOptions.coin.name]; + } + }); return configs; };