Better logging for various components, changed example payment intervals from 10 seconds to 60 seconds. Added more coins and example pool configs.

This commit is contained in:
Matt 2014-03-30 17:04:54 -06:00
parent 9b3d5766df
commit b7e7916736
15 changed files with 263 additions and 120 deletions

7
coins/copperbars.json Normal file
View File

@ -0,0 +1,7 @@
{
"name": "Copperbars",
"symbol": "CPR",
"algorithm": "scrypt-jane",
"chainStartTime": 1376184687,
"txMessages": false
}

View File

@ -143,7 +143,7 @@ var spawnPoolWorkers = function(portalConfig, poolConfigs){
i++;
if (i === numForks){
clearInterval(spawnInterval);
logger.debug('Master', 'PoolSpawner', 'Spawned pools for all ' + numForks + ' configured forks');
logger.debug('Master', 'PoolSpawner', 'Spawned ' + Object.keys(poolConfigs).length + ' pool(s) on ' + numForks + ' thread(s)');
}
}, 250);

View File

@ -9,70 +9,120 @@ module.exports = function(logger){
var poolConfigs = JSON.parse(process.env.pools);
var enabledPools = [];
Object.keys(poolConfigs).forEach(function(coin) {
SetupForPool(logger, poolConfigs[coin]);
var poolOptions = poolConfigs[coin];
if (poolOptions.shareProcessing &&
poolOptions.shareProcessing.internal &&
poolOptions.shareProcessing.internal.enabled)
enabledPools.push(coin);
});
async.filter(enabledPools, function(coin, callback){
SetupForPool(logger, poolConfigs[coin], function(setupResults){
callback(setupResults);
});
}, function(coins){
coins.forEach(function(coin){
var poolOptions = poolConfigs[coin];
var processingConfig = poolOptions.shareProcessing.internal;
var logSystem = 'Payments';
var logComponent = coin;
logger.debug(logSystem, logComponent, 'Payment processing setup to run every '
+ processingConfig.paymentInterval + ' second(s) with daemon ('
+ processingConfig.daemon.user + '@' + processingConfig.daemon.host + ':' + processingConfig.daemon.port
+ ') and redis (' + processingConfig.redis.host + ':' + processingConfig.redis.port + ')');
});
});
};
function SetupForPool(logger, poolOptions){
if (!poolOptions.shareProcessing ||
!poolOptions.shareProcessing.internal ||
!poolOptions.shareProcessing.internal.enabled)
return;
function SetupForPool(logger, poolOptions, setupFinished){
var coin = poolOptions.coin.name;
var processingConfig = poolOptions.shareProcessing.internal;
var logSystem = 'Payments';
var logComponent = coin;
var daemon = new Stratum.daemon.interface([processingConfig.daemon]);
daemon.once('online', function(){
logger.debug(logSystem, logComponent, 'Connected to daemon for payment processing');
daemon.cmd('validateaddress', [poolOptions.address], function(result){
if (!result[0].response || !result[0].response.ismine){
logger.error(logSystem, logComponent,
'Daemon does not own pool address - payment processing can not be done with this daemon');
}
});
}).once('connectionFailed', function(error){
logger.error(logSystem, logComponent, 'Failed to connect to daemon for payment processing: ' +
JSON.stringify(error));
}).on('error', function(error){
logger.error(logSystem, logComponent, 'Daemon error ' + JSON.stringify(error));
}).init();
var daemon;
var redisClient;
async.parallel([
function(callback){
daemon = new Stratum.daemon.interface([processingConfig.daemon]);
daemon.once('online', function(){
daemon.cmd('validateaddress', [poolOptions.address], function(result){
if (!result[0].response || !result[0].response.ismine){
logger.error(logSystem, logComponent,
'Daemon does not own pool address - payment processing can not be done with this daemon');
return;
}
callback()
});
}).once('connectionFailed', function(error){
logger.error(logSystem, logComponent, 'Failed to connect to daemon for payment processing: config ' +
JSON.stringify(processingConfig.daemon) + ', error: ' +
JSON.stringify(error));
callback('Error connecting to deamon');
}).on('error', function(error){
logger.error(logSystem, logComponent, 'Daemon error ' + JSON.stringify(error));
}).init();
},
function(callback){
redisClient = redis.createClient(processingConfig.redis.port, processingConfig.redis.host);
redisClient.on('ready', function(){
if (callback) {
callback();
callback = null;
return;
}
logger.debug(logSystem, logComponent, 'Connected to redis at '
+ processingConfig.redis.host + ':' + processingConfig.redis.port + ' for payment processing');
}).on('end', function(){
logger.error(logSystem, logComponent, 'Connection to redis database as been ended');
}).once('error', function(){
if (callback) {
logger.error(logSystem, logComponent, 'Failed to connect to redis at '
+ processingConfig.redis.host + ':' + processingConfig.redis.port + ' for payment processing');
callback('Error connecting to redis');
callback = null;
}
});
}
], function(err){
if (err){
setupFinished(false);
return;
}
setInterval(function(){
try {
processPayments();
} catch(e){
throw e;
}
}, processingConfig.paymentInterval * 1000);
setTimeout(processPayments, 100);
setupFinished(true);
});
var connectToRedis = function(){
var reconnectTimeout;
redisClient = redis.createClient(processingConfig.redis.port, processingConfig.redis.host);
redisClient.on('ready', function(){
clearTimeout(reconnectTimeout);
logger.debug(logSystem, logComponent, 'Successfully connected to redis database');
})/*).on('error', function(err){
logger.error(logSystem, logComponent, 'Redis client had an error: ' + JSON.stringify(err))
})*/.on('end', function(){
logger.error(logSystem, logComponent, 'Connection to redis database as been ended');
logger.warning(logSystem, logComponent, 'Trying reconnection to redis in 3 seconds...');
reconnectTimeout = setTimeout(function(){
connectToRedis();
}, 3000);
});
};
connectToRedis();
/* Number.toFixed gives us the decimal places we want, but as a string. parseFloat turns it back into number
@ -124,30 +174,6 @@ function SetupForPool(logger, poolOptions){
});
},
/* First get data from all pending blocks via batch RPC call, we need the coinbase txHash. */
/*(function(rounds, callback){
var batchRPCcommand = rounds.map(function(r){
return ['getblock', [r.solution]];
});
daemon.batchCmd(batchRPCcommand, function(error, blocks) {
if (error || !blocks) {
callback('Check finished - daemon rpc error with batch gettransactions ' +
JSON.stringify(error));
return;
}
blocks.forEach(function (b, i) {
if (b.error || b.result.hash !== rounds[i].solution){
logger.error(logSystem, logComponent, "Did daemon drop a block? " + rounds[i].solution);
return;
}
rounds[i].txHash = b.result.tx[0];
});
callback(null, rounds);
});
},*/
/* Does a batch rpc call to daemon with all the transaction hashes to see if they are confirmed yet.
It also adds the block reward amount to the round object - which the daemon gives also gives us. */
function(rounds, callback){
@ -535,7 +561,7 @@ function SetupForPool(logger, poolOptions){
var paymentProcessTime = Date.now() - startPaymentProcess;
if (error)
logger.debug(logSystem, logComponent, '[' + paymentProcessTime + 'ms] ' + error);
logger.debug(logSystem, logComponent, '[Took ' + paymentProcessTime + 'ms] ' + error);
else{
logger.debug(logSystem, logComponent, '[' + paymentProcessTime + 'ms] ' + result);
@ -579,14 +605,4 @@ function SetupForPool(logger, poolOptions){
};
setInterval(function(){
try {
processPayments();
} catch(e){
throw e;
}
}, processingConfig.paymentInterval * 1000);
setTimeout(processPayments, 100);
};

View File

@ -13,11 +13,12 @@ module.exports = function(logger){
var poolConfigs = JSON.parse(process.env.pools);
var portalConfig = JSON.parse(process.env.portalConfig);
var forkId = process.env.forkId;
var forkId = process.env.forkId;
var pools = {};
var pools = {};
var proxyStuff = {};
var proxyStuff = {}
//Handle messages from master process sent via IPC
process.on('message', function(message) {
switch(message.type){
@ -52,7 +53,7 @@ module.exports = function(logger){
var logSystem = 'Pool';
var logComponent = coin;
var logSubCat = 'Fork ' + forkId;
var logSubCat = 'Thread ' + (parseInt(forkId) + 1);
var handlers = {

View File

@ -20,31 +20,23 @@ module.exports = function(logger, poolConfig){
var redisConfig = internalConfig.redis;
var coin = poolConfig.coin.name;
var logSystem = 'Shares';
var forkId = process.env.forkId;
var logSystem = 'Pool';
var logComponent = coin;
var logSubCat = 'Thread ' + (parseInt(forkId) + 1);
var connection;
var connection = redis.createClient(redisConfig.port, redisConfig.host);
function connect(){
var reconnectTimeout;
connection = redis.createClient(redisConfig.port, redisConfig.host);
connection.on('ready', function(){
clearTimeout(reconnectTimeout);
logger.debug(logSystem, 'redis', 'Successfully connected to redis database');
});
connection.on('error', function(err){
logger.error(logSystem, 'redis', 'Redis client had an error: ' + JSON.stringify(err))
});
connection.on('end', function(){
logger.error(logSystem, 'redis', 'Connection to redis database as been ended');
logger.warning(logSystem, 'redis', 'Trying reconnection in 3 seconds...');
reconnectTimeout = setTimeout(function(){
connect();
}, 3000);
});
}
connect();
connection.on('ready', function(){
logger.debug(logSystem, logComponent, logSubCat, 'Share processing setup with redis (' + redisConfig.host +
':' + redisConfig.port + ')');
});
connection.on('error', function(err){
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');
});
@ -78,9 +70,9 @@ module.exports = function(logger, poolConfig){
connection.multi(redisCommands).exec(function(err, replies){
if (err)
logger.error(logSystem, 'redis', 'Error with share processor multi ' + JSON.stringify(err));
logger.error(logSystem, logComponent, logSubCat, 'Error with share processor multi ' + JSON.stringify(err));
else
logger.debug(logSystem, 'redis', 'Share data and stats recorded');
logger.debug(logSystem, logComponent, logSubCat, 'Share data and stats recorded');
});

View File

@ -140,12 +140,11 @@ module.exports = function(logger, portalConfig, poolConfigs){
});
var shareMultiplier = algos[coinStats.algorithm].multiplier || 0;
var hashratePre = shareMultiplier * coinStats.shares / portalConfig.website.hashrateWindow;
console.log([hashratePre, shareMultiplier, coinStats.shares, portalConfig.website.hashrateWindow]);
coinStats.hashrate = hashratePre / 1e3 | 0;
portalStats.global.hashrate += coinStats.hashrate;
portalStats.global.workers += Object.keys(coinStats.workers).length;
coinStats.hashrates;
coinStats.shares;
delete coinStats.hashrates;
delete coinStats.shares;
});
_this.stats = portalStats;

View File

@ -0,0 +1,64 @@
{
"enabled": false,
"coin": "bitcoin.json",
"shareProcessing": {
"internal": {
"enabled": true,
"validateWorkerAddress": true,
"paymentInterval": 60,
"minimumPayment": 100.001,
"minimumReserve": 10,
"feePercent": 0.02,
"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

@ -6,7 +6,7 @@
"internal": {
"enabled": true,
"validateWorkerAddress": true,
"paymentInterval": 10,
"paymentInterval": 60,
"minimumPayment": 100.001,
"minimumReserve": 10,
"feePercent": 0.02,

View File

@ -11,7 +11,7 @@
"internal": {
"enabled": true,
"validateWorkerAddress": true,
"paymentInterval": 10,
"paymentInterval": 60,
"minimumPayment": 100.001,
"minimumReserve": 10,
"feePercent": 0.02,

View File

@ -6,7 +6,7 @@
"internal": {
"enabled": true,
"validateWorkerAddress": true,
"paymentInterval": 10,
"paymentInterval": 60,
"minimumPayment": 70,
"minimumReserve": 10,
"feePercent": 0.05,

View File

@ -6,7 +6,7 @@
"internal": {
"enabled": true,
"validateWorkerAddress": true,
"paymentInterval": 10,
"paymentInterval": 60,
"minimumPayment": 100.001,
"minimumReserve": 10,
"feePercent": 0.02,

View File

@ -6,7 +6,7 @@
"internal": {
"enabled": false,
"validateWorkerAddress": true,
"paymentInterval": 10,
"paymentInterval": 60,
"minimumPayment": 100.001,
"minimumReserve": 10,
"feePercent": 0.02,

View File

@ -6,7 +6,7 @@
"internal": {
"enabled": true,
"validateWorkerAddress": true,
"paymentInterval": 10,
"paymentInterval": 60,
"minimumPayment": 70,
"minimumReserve": 10,
"feePercent": 0.05,

View File

@ -11,7 +11,7 @@
"internal": {
"enabled": true,
"validateWorkerAddress": true,
"paymentInterval": 10,
"paymentInterval": 60,
"minimumPayment": 100.001,
"minimumReserve": 10,
"feePercent": 0.02,

View File

@ -0,0 +1,64 @@
{
"enabled": false,
"coin": "ultracoin.json",
"shareProcessing": {
"internal": {
"enabled": true,
"validateWorkerAddress": true,
"paymentInterval": 60,
"minimumPayment": 100.001,
"minimumReserve": 10,
"feePercent": 0.02,
"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"
}
]
}