Merge remote-tracking branch 'origin/master' into bluecircle

This commit is contained in:
Jerry Brady 2014-04-02 22:15:14 +00:00
commit df5ed6d29b
21 changed files with 66 additions and 644 deletions

3
.gitignore vendored
View File

@ -1,2 +1,3 @@
node_modules/
.idea/
.idea/
config.json

View File

@ -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
@ -156,7 +156,7 @@ Here is an example of the required fields:
````
For additional documentation how to configure coins *(especially important for scrypt-n and scrypt-jane coins)*
see [these instructions](https://github.com/zone117x/node-stratum-pool/edit/master/README.md#module-usage).
see [these instructions](//github.com/zone117x/node-stratum-pool#module-usage).
##### Pool config
@ -204,16 +204,16 @@ Description of options:
/* (2% default) What percent fee your pool takes from the block reward. */
"feePercent": 0.02,
/* Name of the account to use when moving coin profit within daemon wallet. */
/* Name of the daemon account to use when moving coin profit within daemon wallet. */
"feeCollectAccount": "feesCollected",
/* Your address that receives pool revenue from fees. */
"feeReceiveAddress": "LZz44iyF4zLCXJTU8RxztyyJZBntdS6fvv",
/* (Not implemented yet) How many coins from fee revenue must accumulate on top of the
/* How many coins from fee revenue must accumulate on top of the
minimum reserve amount in order to trigger withdrawal to fee address. The higher
this threshold, the less of your profit goes to transactions fees. */
//"feeWithdrawalThreshold": 5,
"feeWithdrawalThreshold": 5,
/* This daemon is used to send out payments. It MUST be for the daemon that owns the
configured 'address' that receives the block rewards, otherwise the daemon will not
@ -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
@ -255,6 +257,10 @@ Description of options:
job broadcast. */
"txRefreshInterval": 20000,
/* Some miner software is bugged and will consider the pool offline if it doesn't receive
anything for around a minute, so every time we broadcast jobs, set a timeout to rebroadcast
in this many seconds unless we find a new job. Set to zero or remove to disable this. */
"jobRebroadcastTimeout": 55,
//instanceId: 37, //Recommend not using this because a crypto-random one will be generated
@ -263,6 +269,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": {

5
coins/365coin.json Normal file
View File

@ -0,0 +1,5 @@
{
"name": "365coin",
"symbol": "365",
"algorithm": "keccak"
}

View File

@ -1,5 +1,5 @@
{
"name": "Helixcoin",
"symbol": "HXC",
"algorithm": "max"
"algorithm": "keccak"
}

25
init.js
View File

@ -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;
};

View File

@ -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 = ?',

View File

@ -123,9 +123,6 @@ function SetupForPool(logger, poolOptions, setupFinished){
/* Number.toFixed gives us the decimal places we want, but as a string. parseFloat turns it back into number
we don't care about trailing zeros in this case. */
var toPrecision = function(value, precision){
@ -163,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],
@ -194,20 +191,20 @@ function SetupForPool(logger, poolOptions, setupFinished){
txDetails.forEach(function(tx, i){
var round = rounds[i];
if (tx.error && tx.error.code === -5){
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';
}).length;
var dropKicked = rounds.filter(function(r){
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{
@ -301,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;
}
@ -489,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);
@ -536,8 +534,10 @@ function SetupForPool(logger, poolOptions, setupFinished){
finalizeRedisTx();
var totalWorkers = Object.keys(workerPayments).length;
logger.debug(logSystem, logComponent, 'Payments sent, a total of ' + totalAmountUnits + ' ' + poolOptions.coin.symbol +
' was sent to ' + totalWorkers + ' miners');
logger.debug(logSystem, logComponent, 'Payments sent, a total of ' + totalAmountUnits
+ ' ' + poolOptions.coin.symbol + ' was sent to ' + totalWorkers + ' miners');
daemon.cmd('gettransaction', [results[0].response], function(results){
if (results[0].error){
callback('Check finished - error with gettransaction ' + JSON.stringify(results[0].error));
@ -595,11 +595,12 @@ function SetupForPool(logger, poolOptions, setupFinished){
daemon.cmd('sendmany', [processingConfig.feeCollectAccount, withdrawal], function(results){
if (results[0].error){
logger.debug(logSystem, logComponent, 'Profit withdrawal finished - error with sendmany ' + JSON.stringify(results[0].error));
logger.debug(logSystem, logComponent, 'Profit withdrawal finished - error with sendmany '
+ JSON.stringify(results[0].error));
return;
}
logger.debug(logSystem, logComponent, 'Profit sent, a total of ' + withdrawalAmount + ' ' + poolOptions.coin.symbol +
' was sent to ' + processingConfig.feeReceiveAddress);
logger.debug(logSystem, logComponent, 'Profit sent, a total of ' + withdrawalAmount
+ ' ' + poolOptions.coin.symbol + ' was sent to ' + processingConfig.feeReceiveAddress);
});
}
});

View File

@ -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)

View File

@ -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]);
}

View File

@ -1,65 +0,0 @@
{
"enabled": false,
"coin": "bitcoin.json",
"shareProcessing": {
"internal": {
"enabled": true,
"validateWorkerAddress": true,
"paymentInterval": 60,
"minimumPayment": 100.001,
"minimumReserve": 10,
"feePercent": 0.02,
"feeCollectAccount": "feesCollected",
"feeReceiveAddress": "msjLr1XfpB6aAL1wi8e2CDnDSNhF4WrJ5n",
"feeWithdrawalThreshold": 5,
"daemon": {
"host": "localhost",
"port": 18332,
"user": "testuser",
"password": "testpass"
},
"redis": {
"host": "localhost",
"port": 6379
}
},
"mpos": {
"enabled": false,
"host": "localhost",
"port": 3306,
"user": "me",
"password": "mypass",
"database": "ltc",
"stratumAuth": "password"
}
},
"address": "mtCiLWzBy9EpuxzkLwizPYiPFDy69HTd4b",
"blockRefreshInterval": 1000,
"txRefreshInterval": 20000,
"connectionTimeout": 600,
"banning": {
"enabled": true,
"time": 600,
"invalidPercent": 50,
"checkThreshold": 500,
"purgeInterval": 300
},
"ports": {
"6774": {
"diff": 1
}
},
"daemons": [
{
"host": "localhost",
"port": 18332,
"user": "testuser",
"password": "testpass"
}
]
}

View File

@ -1,65 +0,0 @@
{
"enabled": false,
"coin": "darkcoin.json",
"shareProcessing": {
"internal": {
"enabled": true,
"validateWorkerAddress": true,
"paymentInterval": 60,
"minimumPayment": 100.001,
"minimumReserve": 10,
"feePercent": 0.02,
"feeCollectAccount": "feesCollected",
"feeReceiveAddress": "XfkoYutJ8KYtLxZ4TgnMqC6SCmxuc3LEDY",
"feeWithdrawalThreshold": 5,
"daemon": {
"host": "localhost",
"port": 18342,
"user": "darkcoinrpc1",
"password": "testpass"
},
"redis": {
"host": "localhost",
"port": 6379
}
},
"mpos": {
"enabled": false,
"host": "localhost",
"port": 3306,
"user": "me",
"password": "mypass",
"database": "ltc",
"stratumAuth": "password"
}
},
"address": "XfkoYutJ8KYtLxZ4TgnMqC6SCmxuc3LEDY",
"blockRefreshInterval": 1000,
"txRefreshInterval": 20000,
"connectionTimeout": 600,
"banning": {
"enabled": true,
"time": 600,
"invalidPercent": 50,
"checkThreshold": 500,
"purgeInterval": 300
},
"ports": {
"4073": {
"diff": 0.002
}
},
"daemons": [
{
"host": "localhost",
"port": 18342,
"user": "darkcoinrpc1",
"password": "testpass"
}
]
}

View File

@ -1,58 +0,0 @@
{
"enabled": false,
"coin": "execoin.json",
"shareProcessing": {
"internal": {
"enabled": true,
"validateWorkerAddress": true,
"paymentInterval": 60,
"minimumPayment": 100.001,
"minimumReserve": 10,
"feePercent": 0.02,
"feeCollectAccount": "feesCollected",
"feeReceiveAddress": "ESfYVyfh1yZx1AkqJnu6rJje5nWE3f2C3r",
"feeWithdrawalThreshold": 5,
"daemon": {
"host": "localhost",
"port": 19847,
"user": "testuser",
"password": "testpass"
},
"redis": {
"host": "localhost",
"port": 6379
}
},
"mpos": {
"enabled": false,
"host": "localhost",
"port": 3306,
"user": "me",
"password": "mypass",
"database": "ltc",
"stratumAuth": "password"
}
},
"address": "EabPhjVKcmus3LKFViAcwq3dfo8kzqpMkQ",
"blockRefreshInterval": 1000,
"txRefreshInterval": 20000,
"connectionTimeout": 600,
"ports": {
"6368": {
"diff": 8
}
},
"daemons": [
{
"host": "localhost",
"port": 19847,
"user": "testuser",
"password": "testpass"
}
]
}

View File

@ -1,56 +0,0 @@
{
"enabled": false,
"coin": "galleon.json",
"address": "GRAiuGCWLrL8Psdr6pkhLpxrQGHdYfrSEz",
"blockRefreshInterval": 1000,
"txRefreshInterval": 20000,
"connectionTimeout": 600,
"shareProcessing": {
"internal": {
"enabled": true,
"validateWorkerAddress": true,
"paymentInterval": 60,
"minimumPayment": 100.001,
"minimumReserve": 10,
"feePercent": 0.02,
"feeCollectAccount": "feesCollected",
"feeReceiveAddress": "GRAiuGCWLrL8Psdr6pkhLpxrQGHdYfrSEz",
"feeWithdrawalThreshold": 5,
"daemon": {
"host": "localhost",
"port": 19632,
"user": "testuser",
"password": "testpass"
},
"redis": {
"host": "localhost",
"port": 6379
}
}
},
"ports": {
"3537": {
"diff": 4
}
},
"daemons": [
{
"host": "localhost",
"port": 19632,
"user": "testuser",
"password": "testpass"
}
],
"p2p": {
"enabled": false,
"host": "localhost",
"port": 19333,
"protocolVersion": 70002,
"magic": "fcc1b7dc"
}
}

View File

@ -1,57 +0,0 @@
{
"enabled": false,
"coin": "helixcoin.json",
"shareProcessing": {
"internal": {
"enabled": true,
"validateWorkerAddress": true,
"paymentInterval": 60,
"minimumPayment": 70,
"minimumReserve": 10,
"feePercent": 0.05,
"feeCollectAccount": "feesCollected",
"feeReceiveAddress": "mppaGeNaSbG1Q7S6V3gL5uJztMhucgL9Vh",
"feeWithdrawalThreshold": 5,
"daemon": {
"host": "localhost",
"port": 19332,
"user": "litecoinrpc",
"password": "testnet"
},
"redis": {
"host": "localhost",
"port": 6379
}
}
},
"address": "H9xyrh45LzLX4uXCP6jG6ZGrWho8srUgiG",
"blockRefreshInterval": 1000,
"txRefreshInterval": 20000,
"connectionTimeout": 600,
"ports": {
"3737": {
"diff": 0.2
}
},
"daemons": [
{
"host": "localhost",
"port": 16385,
"user": "testuser",
"password": "testpass"
}
],
"p2p": {
"enabled": false,
"host": "localhost",
"port": 19333,
"protocolVersion": 70002,
"magic": "fcc1b7dc"
}
}

View File

@ -1,66 +0,0 @@
{
"enabled": false,
"coin": "hirocoin.json",
"shareProcessing": {
"internal": {
"enabled": true,
"validateWorkerAddress": true,
"paymentInterval": 60,
"minimumPayment": 100.001,
"minimumReserve": 10,
"feePercent": 0.02,
"feeCollectAccount": "feesCollected",
"feeReceiveAddress": "HR6WNSR19kvaXSbwKymrba6uNx36BBjinS",
"feeWithdrawalThreshold": 5,
"daemon": {
"host": "localhost",
"port": 19389,
"user": "hirocoin",
"password": "testpass"
},
"redis": {
"host": "localhost",
"port": 6379
}
},
"mpos": {
"enabled": false,
"host": "localhost",
"port": 3306,
"user": "me",
"password": "mypass",
"database": "ltc",
"stratumAuth": "password"
}
},
"address": "HR6WNSR19kvaXSbwKymrba6uNx36BBjinS",
"blockRefreshInterval": 1000,
"txRefreshInterval": 20000,
"connectionTimeout": 600,
"banning": {
"enabled": true,
"time": 600,
"invalidPercent": 50,
"checkThreshold": 500,
"purgeInterval": 300
},
"ports": {
"3073": {
"diff": 0.002
}
},
"daemons": [
{
"host": "localhost",
"port": 19389,
"user": "hirocoin",
"password": "testpass"
}
]
}

View File

@ -1,65 +0,0 @@
{
"enabled": false,
"coin": "hobonickels.json",
"shareProcessing": {
"internal": {
"enabled": false,
"validateWorkerAddress": true,
"paymentInterval": 60,
"minimumPayment": 100.001,
"minimumReserve": 10,
"feePercent": 0.02,
"feeReceiveAddress": "EhA4HXF7VPWfnV8TXerAP6p12BiEpXbiYR",
"feeWithdrawalThreshold": 5,
"daemon": {
"host": "localhost",
"port": 19339,
"user": "hobonickelsrpc",
"password": "testpass"
},
"redis": {
"host": "localhost",
"port": 6379
}
},
"mpos": {
"enabled": false,
"host": "localhost",
"port": 3306,
"user": "me",
"password": "mypass",
"database": "ltc",
"stratumAuth": "password"
}
},
"address": "EzGiarU2S56jyRkYpS7FKssXCS6AAJChdU",
"blockRefreshInterval": 1000,
"txRefreshInterval": 20000,
"connectionTimeout": 600,
"banning": {
"enabled": true,
"time": 600,
"invalidPercent": 50,
"checkThreshold": 500,
"purgeInterval": 300
},
"ports": {
"3033": {
"diff": 8
}
},
"daemons": [
{
"host": "localhost",
"port": 19339,
"user": "hobonickelsrpc",
"password": "testpass"
}
]
}

View File

@ -6,7 +6,7 @@
"internal": {
"enabled": true,
"validateWorkerAddress": true,
"paymentInterval": 60,
"paymentInterval": 20,
"minimumPayment": 70,
"minimumReserve": 10,
"feePercent": 0.05,
@ -35,10 +35,10 @@
}
},
"address": "n4jSe18kZMCdGcZqaYprShXW6EH1wivUK1",
"blockRefreshInterval": 1000,
"txRefreshInterval": 20000,
"jobRebroadcastTimeout": 55,
"connectionTimeout": 600,
"banning": {
@ -50,7 +50,7 @@
},
"ports": {
"3008":{
"3008": {
"diff": 8,
"varDiff": {
"minDiff": 8,

View File

@ -1,48 +0,0 @@
{
"enabled": false,
"coin": "maxcoin.json",
"address": "tKWkadAkT2vqK6v2PHLJmV1RTVvF7XZEgN",
"blockRefreshInterval": 1000,
"txRefreshInterval": 20000,
"connectionTimeout": 600,
"shareProcessing": {
"internal": {
"enabled": true,
"validateWorkerAddress": true,
"paymentInterval": 60,
"minimumPayment": 100.001,
"minimumReserve": 10,
"feePercent": 0.02,
"feeCollectAccount": "feesCollected",
"feeReceiveAddress": "tQ2TKXXk2jh7EX2RJQ4ZxpZYEdRx7fdiaw",
"feeWithdrawalThreshold": 5,
"daemon": {
"host": "localhost",
"port": 27932,
"user": "testuser",
"password": "testpass"
},
"redis": {
"host": "localhost",
"port": 6379
}
}
},
"ports": {
"5547": {
"diff": 2
}
},
"daemons": [
{
"host": "localhost",
"port": 27932,
"user": "testuser",
"password": "testpass"
}
]
}

View File

@ -1,65 +0,0 @@
{
"enabled": false,
"coin": "ultracoin.json",
"shareProcessing": {
"internal": {
"enabled": true,
"validateWorkerAddress": true,
"paymentInterval": 60,
"minimumPayment": 100.001,
"minimumReserve": 10,
"feePercent": 0.02,
"feeCollectAccount": "feesCollected",
"feeReceiveAddress": "UZ3cz7EKjC4eRKbhiN9tA6xcaDGSVoESc8",
"feeWithdrawalThreshold": 5,
"daemon": {
"host": "localhost",
"port": 18365,
"user": "testuser",
"password": "testpass"
},
"redis": {
"host": "localhost",
"port": 6379
}
},
"mpos": {
"enabled": false,
"host": "localhost",
"port": 3306,
"user": "me",
"password": "mypass",
"database": "ltc",
"stratumAuth": "password"
}
},
"address": "UhyKVr4m516TPsrLwm91pYL4f99VGrJ1oC",
"blockRefreshInterval": 1000,
"txRefreshInterval": 20000,
"connectionTimeout": 600,
"banning": {
"enabled": true,
"time": 600,
"invalidPercent": 50,
"checkThreshold": 500,
"purgeInterval": 300
},
"ports": {
"6856": {
"diff": 8
}
},
"daemons": [
{
"host": "localhost",
"port": 18365,
"user": "testuser",
"password": "testpass"
}
]
}

View File

@ -1,58 +0,0 @@
{
"enabled": false,
"coin": "vertcoin.json",
"shareProcessing": {
"internal": {
"enabled": true,
"validateWorkerAddress": true,
"paymentInterval": 60,
"minimumPayment": 100.001,
"minimumReserve": 10,
"feePercent": 0.02,
"feeCollectAccount": "feesCollected",
"feeReceiveAddress": "VrcunuCcNUULMBoiw66v9SAdQq2m1FpP3C",
"feeWithdrawalThreshold": 5,
"daemon": {
"host": "localhost",
"port": 13295,
"user": "testuser",
"password": "testpass"
},
"redis": {
"host": "localhost",
"port": 6379
}
},
"mpos": {
"enabled": false,
"host": "localhost",
"port": 3306,
"user": "me",
"password": "mypass",
"database": "ltc",
"stratumAuth": "password"
}
},
"address": "VrcunuCcNUULMBoiw66v9SAdQq2m1FpP3C",
"blockRefreshInterval": 1000,
"txRefreshInterval": 20000,
"connectionTimeout": 600,
"ports": {
"6381": {
"diff": 8
}
},
"daemons": [
{
"host": "localhost",
"port": 13295,
"user": "testuser",
"password": "testpass"
}
]
}