mirror of https://github.com/BTCPrivate/z-nomp.git
More development for internal payment processing. Added new stratumpool module options.
This commit is contained in:
parent
d33730c274
commit
27550caa39
62
README.md
62
README.md
|
@ -83,30 +83,43 @@ Description of options:
|
||||||
{
|
{
|
||||||
"disabled": false, //Set this to true and a pool will not be created from this config file
|
"disabled": false, //Set this to true and a pool will not be created from this config file
|
||||||
"coin": "litecoin", //This MUST be a reference to the 'name' field in your coin's config file
|
"coin": "litecoin", //This MUST be a reference to the 'name' field in your coin's config file
|
||||||
"address": "mi4iBXbBsydtcc5yFmsff2zCFVX4XG7qJc", //address to where block rewards are given
|
"address": "mi4iBXbBsydtcc5yFmsff2zCFVX4XG7qJc", //Address to where block rewards are given
|
||||||
"blockRefreshInterval": 1000 //how often to poll RPC daemons for new blocks, in milliseconds
|
"blockRefreshInterval": 1000 //How often to poll RPC daemons for new blocks, in milliseconds
|
||||||
//instanceId: 37, //Recommend not using this because a crypto-random one will be generated
|
//instanceId: 37, //Recommend not using this because a crypto-random one will be generated
|
||||||
|
|
||||||
|
/* Some attackers will create thousands of workers that use up all available socket connections,
|
||||||
|
usually the workers are zombies and don't submit shares after connecting. This features
|
||||||
|
detects those and disconnects them */
|
||||||
|
"connectionTimeout": 120, //Remove workers that haven't been in contact for this many seconds
|
||||||
|
|
||||||
|
/* If a worker is submitting a good deal of invalid shares we can temporarily ban them to
|
||||||
|
reduce system/network load. Also useful to fight against flooding attacks. */
|
||||||
|
"banning": {
|
||||||
|
"enabled": true,
|
||||||
|
"time": 600, //How many seconds to ban worker for
|
||||||
|
"invalidPercent": 50, //What percent of invalid shares triggers ban
|
||||||
|
"checkThreshold": 500 //Check invalid percent when this many shares have been submitted
|
||||||
|
},
|
||||||
|
|
||||||
/* Each pool can have as many ports for your miners to connect to as you wish. Each port can
|
/* Each pool can have as many ports for your miners to connect to as you wish. Each port can
|
||||||
be configured to use its own pool difficulty and variable difficulty settings. varDiff is
|
be configured to use its own pool difficulty and variable difficulty settings. varDiff is
|
||||||
optional and will only be used for the ports you configure it for. */
|
optional and will only be used for the ports you configure it for. */
|
||||||
"ports": {
|
"ports": {
|
||||||
"3032": { //a port for your miners to connect to
|
"3032": { //A port for your miners to connect to
|
||||||
"diff": 32, //the pool difficulty for this port
|
"diff": 32, //the pool difficulty for this port
|
||||||
|
|
||||||
/* Variable difficulty is a feature that will automatically adjust difficulty for
|
/* Variable difficulty is a feature that will automatically adjust difficulty for
|
||||||
individual miners based on their hashrate in order to lower networking overhead */
|
individual miners based on their hashrate in order to lower networking overhead */
|
||||||
"varDiff": {
|
"varDiff": {
|
||||||
"minDiff": 8, //minimum difficulty
|
"minDiff": 8, //Minimum difficulty
|
||||||
"maxDiff": 512, //network difficulty will be used if it is lower than this
|
"maxDiff": 512, //Network difficulty will be used if it is lower than this
|
||||||
"targetTime": 15, //try to get 1 share per this many seconds
|
"targetTime": 15, //Try to get 1 share per this many seconds
|
||||||
"retargetTime": 90, //check to see if we should retarget every this many seconds
|
"retargetTime": 90, //Check to see if we should retarget every this many seconds
|
||||||
"variancePercent": 30 //allow time to very this % from target without retargeting
|
"variancePercent": 30 //Allow time to very this % from target without retargeting
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"3256": { //another port for your miners to connect to, this port does not use varDiff
|
"3256": { //Another port for your miners to connect to, this port does not use varDiff
|
||||||
"diff": 256 //the pool difficulty
|
"diff": 256 //The pool difficulty
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -115,14 +128,21 @@ Description of options:
|
||||||
and disable mpos which will allow this portal to handle all share payments.2) Enable mpos
|
and disable mpos which will allow this portal to handle all share payments.2) Enable mpos
|
||||||
and disabled internal which wil allow MPOS to handle all share payments. */
|
and disabled internal which wil allow MPOS to handle all share payments. */
|
||||||
"shareProcessing": {
|
"shareProcessing": {
|
||||||
"internal": { //enabled this options for share payments to be processed and sent locally
|
"internal": { //Enabled this options for share payments to be processed and sent locally
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
/* When workers connect, to receive payments, their address must be used as the worker
|
/* When workers connect, to receive payments, their address must be used as the worker
|
||||||
name. If this option is true, on worker authentication, their address will be verified
|
name. If this option is true, on worker authentication, their address will be verified
|
||||||
via a validateaddress API call to the daemon. Miners with invalid addresses will be
|
via a validateaddress API call to the daemon. Miners with invalid addresses will be
|
||||||
rejected. */
|
rejected. */
|
||||||
"validateWorkerAddress": true,
|
"validateWorkerAddress": true,
|
||||||
"paymentInterval": 30, //(seconds) check for confirmed blocks for sending payments
|
"paymentInterval": 30, //(seconds) Check for confirmed blocks for sending payments
|
||||||
|
/* Minimum number of coins that a miner must earn before sending payment. Typically,
|
||||||
|
a higher minimum means transactions fees (more profit for you) but miners see payments
|
||||||
|
less frequently (which they may dislike). Opposite for a lower minimum payment. */
|
||||||
|
"minimumPayment": 0.001,
|
||||||
|
"feePercent": 0.02, //(2% default) What percent fee your pool takes from the block reward
|
||||||
|
/* Your address that receives pool revenue from fees */
|
||||||
|
"feeReceiveAddress": "LZz44iyF4zLCXJTU8RxztyyJZBntdS6fvv",
|
||||||
/* This daemon is used to send out payments. It MUST be for the daemon that owns the
|
/* This daemon is used to send out payments. It MUST be for the daemon that owns the
|
||||||
'address' field above, otherwise the daemon will not be able to confirm blocks
|
'address' field above, otherwise the daemon will not be able to confirm blocks
|
||||||
or sent out payments. */
|
or sent out payments. */
|
||||||
|
@ -133,13 +153,13 @@ Description of options:
|
||||||
"password": "testnet"
|
"password": "testnet"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mpos": { //enabled this and shares will be inserted into share table in a MySql database
|
"mpos": { //Enabled this and shares will be inserted into share table in a MySQL database
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"host": "localhost",
|
"host": "localhost", //MySQL db host
|
||||||
"port": 3306,
|
"port": 3306, //MySQL db port
|
||||||
"user": "me",
|
"user": "me", //MySQL db user
|
||||||
"password": "mypass",
|
"password": "mypass", //MySQL db password
|
||||||
"database": "ltc",
|
"database": "ltc", //MySQL db database name
|
||||||
/* For when miner's authenticate: set to "password" for both worker name and password to
|
/* For when miner's authenticate: set to "password" for both worker name and password to
|
||||||
be checked for in the database, set to "worker" for only work name to be checked, or
|
be checked for in the database, set to "worker" for only work name to be checked, or
|
||||||
don't use this option (set to "none") for no auth checks */
|
don't use this option (set to "none") for no auth checks */
|
||||||
|
@ -151,13 +171,13 @@ Description of options:
|
||||||
/* RPC daemons for block update polling and submitting blocks - recommended to have at least two
|
/* RPC daemons for block update polling and submitting blocks - recommended to have at least two
|
||||||
for redundancy in case one dies or goes out-of-sync */
|
for redundancy in case one dies or goes out-of-sync */
|
||||||
"daemons": [
|
"daemons": [
|
||||||
{ //main daemon instance
|
{ //Main daemon instance
|
||||||
"host": "localhost",
|
"host": "localhost",
|
||||||
"port": 19332,
|
"port": 19332,
|
||||||
"user": "litecoinrpc",
|
"user": "litecoinrpc",
|
||||||
"password": "testnet"
|
"password": "testnet"
|
||||||
},
|
},
|
||||||
{ //backup daemon instance
|
{ //Backup daemon instance
|
||||||
"host": "localhost",
|
"host": "localhost",
|
||||||
"port": 19344,
|
"port": 19344,
|
||||||
"user": "litecoinrpc",
|
"user": "litecoinrpc",
|
||||||
|
@ -181,7 +201,7 @@ Description of options:
|
||||||
*/
|
*/
|
||||||
"magic": "fcc1b7dc",
|
"magic": "fcc1b7dc",
|
||||||
|
|
||||||
// Found in src as the PROTOCOL_VERSION variable, for example: http://git.io/KjuCrw
|
//Found in src as the PROTOCOL_VERSION variable, for example: http://git.io/KjuCrw
|
||||||
"protocolVersion": 70002,
|
"protocolVersion": 70002,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
15
init.js
15
init.js
|
@ -84,15 +84,26 @@ if (cluster.isMaster){
|
||||||
return config.clustering.forks;
|
return config.clustering.forks;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
var workerIds = {};
|
||||||
|
|
||||||
for (var i = 0; i < numForks; i++) {
|
for (var i = 0; i < numForks; i++) {
|
||||||
cluster.fork({
|
var worker = cluster.fork({
|
||||||
forkId: i,
|
forkId: i,
|
||||||
pools: serializedConfigs
|
pools: serializedConfigs
|
||||||
});
|
});
|
||||||
|
workerIds[worker.process.pid] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
cluster.on('exit', function(worker, code, signal) {
|
cluster.on('exit', function(worker, code, signal) {
|
||||||
logError('workerFork', 'system', 'fork with PID ' + worker.process.pid + ' died');
|
var diedPid = worker.process.pid;
|
||||||
|
var forkId = workerIds[diedPid]
|
||||||
|
logError('poolWorker', 'system', 'Fork ' + forkId + ' died, spawning replacement worker...');
|
||||||
|
var worker = cluster.fork({
|
||||||
|
forkId: forkId,
|
||||||
|
pools: serializedConfigs
|
||||||
|
});
|
||||||
|
delete workerIds[diedPid];
|
||||||
|
workerIds[worker.process.pid] = forkId;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
/**
|
||||||
|
* Created by Matt on 3/5/14.
|
||||||
|
*/
|
||||||
|
var daemon = new Stratum.daemon.interface([internalConfig.daemon]);
|
||||||
|
daemon.once('online', function(){
|
||||||
|
logger.debug('system', 'Connected to daemon for payment processing');
|
||||||
|
}).once('connectionFailed', function(error){
|
||||||
|
logger.error('system', 'Failed to connect to daemon for payment processing: ' + JSON.stringify(error));
|
||||||
|
}).on('error', function(error){
|
||||||
|
logger.error('system', error);
|
||||||
|
}).init();
|
|
@ -106,14 +106,14 @@ module.exports = function(logger){
|
||||||
var shareData = JSON.stringify(data);
|
var shareData = JSON.stringify(data);
|
||||||
|
|
||||||
if (data.solution && !isValidBlock)
|
if (data.solution && !isValidBlock)
|
||||||
poolLogger.debug('client', 'We thought a block solution was found but it was rejected by the daemon, share data: ' + shareData);
|
poolLogger.debug('client', 'We thought a block solution was found but it was rejected by the daemon, share data: ' + data);
|
||||||
else if (isValidBlock)
|
else if (isValidBlock)
|
||||||
poolLogger.debug('client', 'Block found, solution: ' + shareData.solution);
|
poolLogger.debug('client', 'Block found, solution: ' + data.solution);
|
||||||
|
|
||||||
if (isValidShare)
|
if (isValidShare)
|
||||||
poolLogger.debug('client', 'Valid share submitted, share data: ' + shareData);
|
poolLogger.debug('client', 'Valid share submitted, share data: ' + data);
|
||||||
else if (!isValidShare)
|
else if (!isValidShare)
|
||||||
poolLogger.debug('client', 'Invalid share submitted, share data: ' + shareData)
|
poolLogger.debug('client', 'Invalid share submitted, share data: ' + data)
|
||||||
|
|
||||||
|
|
||||||
handlers.share(isValidShare, isValidBlock, data)
|
handlers.share(isValidShare, isValidBlock, data)
|
||||||
|
|
|
@ -1,17 +1,34 @@
|
||||||
var redis = require('redis');
|
var redis = require('redis');
|
||||||
|
var Stratum = require('stratum-pool');
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
This module deals with handling shares when in internal payment processing mode. It connects to a redis
|
||||||
|
database and inserts shares with the database structure of:
|
||||||
|
|
||||||
|
key: coin_name + ':' + block_height
|
||||||
|
value: a hash with..
|
||||||
|
key:
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
module.exports = function(logger, poolConfig){
|
module.exports = function(logger, poolConfig){
|
||||||
|
|
||||||
var redisConfig = poolConfig.shareProcessing.internal.redis;
|
var internalConfig = poolConfig.shareProcessing.internal;
|
||||||
|
var redisConfig = internalConfig.redis;
|
||||||
var coin = poolConfig.coin.name;
|
var coin = poolConfig.coin.name;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var connection;
|
var connection;
|
||||||
|
|
||||||
function connect(){
|
function connect(){
|
||||||
|
|
||||||
var reconnectTimeout;
|
var reconnectTimeout;
|
||||||
|
|
||||||
var connection = redis.createClient(redisConfig.port, redisConfig.host);
|
connection = redis.createClient(redisConfig.port, redisConfig.host);
|
||||||
connection.on('ready', function(){
|
connection.on('ready', function(){
|
||||||
clearTimeout(reconnectTimeout);
|
clearTimeout(reconnectTimeout);
|
||||||
logger.debug('redis', 'Successfully connected to redis database');
|
logger.debug('redis', 'Successfully connected to redis database');
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
/* TODO
|
||||||
|
|
||||||
|
listen on port 80 for requests, maybe use express.
|
||||||
|
read website folder files into memory, and use fs.watch to reload changes to any files into memory
|
||||||
|
|
||||||
|
on some interval, apply a templating process to it with the latest api stats. on http requests, serve
|
||||||
|
this templated file and the other resources in memory.
|
||||||
|
|
||||||
|
ideally, all css/js should be included in the html file (try to avoid images, uses embeddable svg)
|
||||||
|
this would give us one file to have to serve
|
||||||
|
|
||||||
|
*/
|
|
@ -4,6 +4,15 @@
|
||||||
"address": "mi4iBXbBsydtcc5yFmsff2zCFVX4XG7qJc",
|
"address": "mi4iBXbBsydtcc5yFmsff2zCFVX4XG7qJc",
|
||||||
"blockRefreshInterval": 1000,
|
"blockRefreshInterval": 1000,
|
||||||
|
|
||||||
|
"connectionTimeout": 120,
|
||||||
|
|
||||||
|
"banning": {
|
||||||
|
"enabled": true,
|
||||||
|
"time": 600,
|
||||||
|
"invalidPercent": 50,
|
||||||
|
"checkThreshold": 500
|
||||||
|
},
|
||||||
|
|
||||||
"ports": {
|
"ports": {
|
||||||
"3032": {
|
"3032": {
|
||||||
"diff": 32,
|
"diff": 32,
|
||||||
|
@ -23,8 +32,11 @@
|
||||||
"shareProcessing": {
|
"shareProcessing": {
|
||||||
"internal": {
|
"internal": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"validateWorkAddress": true,
|
"validateWorkerAddress": true,
|
||||||
"paymentInterval": 30,
|
"paymentInterval": 30,
|
||||||
|
"minimumPayment": 0.001,
|
||||||
|
"feePercent": 0.02,
|
||||||
|
"feeReceiveAddress": "LZz44iyF4zLCXJTU8RxztyyJZBntdS6fvv",
|
||||||
"daemon": {
|
"daemon": {
|
||||||
"host": "localhost",
|
"host": "localhost",
|
||||||
"port": 19332,
|
"port": 19332,
|
||||||
|
|
Loading…
Reference in New Issue