This software is an extremely efficient, highly scalable, all-in-one, easy to setup cryptocurrency mining/staking pool written entirely in Node.js. It contains a stratum poolserver; reward/payment/share processor; and a responsive user-friendly front-end website featuring mining/staking instructions and in-depth live statistics.
This is beta software. All of the following are things that can change and break an existing server 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.
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.
Coin switching & auto-exchanging for payouts in BTC/LTC to miners is a feature that very likely will not be included in this project.
For the pool server it uses the highly efficient cryptocurrency-stratum-pool module which supports vardiff, PoW, PoS, transaction messages, anti-DDoS, IP banning, and many hashing algorithms.
The portal has an MPOS compatibility mode so that it can function as a drop-in-replacement for python-stratum-mining. This mode can be enabled in the configuration and will insert shares into a MySQL database in the format which MPOS expects.
Multi-pool ability - this software was built from the ground up to run with multiple coins simultaneously (which can have different properties and hashing algorithms). It can be used to create a pool for a single coin or for multiple coins at once. The pools use clustering to load balance across multiple CPU cores.
For reward/payment processing, shares are inserted into Redis (a fast NoSQL key/value store). The PROP (proportional) reward system is used with Redis Transactions for secure and super speedy payouts. There is zero risk to the pool operator. Shares from rounds resulting in orphaned blocks will be merged into shares for the current round so that each and every share will be rewarded.
This portal does not have user accounts/logins/registrations. Instead, miners simply use their coin address for stratum authentication.
Coin-switching ports using coin-networks and crypto-exchange APIs to detect profitability. Miner's connect to these ports with their public key which the server uses to derive an address for any coin needed to be paid out.
Cryptocurrency Pool Server has some implicit security advantages for pool operators and miners:
Discord
Having problems getting the portal running due to some module dependency error? It's probably because you didn't follow the instructions in this README. Please read the usage instructions including requirements and downloading/installing. If you've followed the instructions completely and are still having problems then open an issue here on github or join our #cryptopools-github Discord channel and explain your problem :).
If your pool uses Cryptocurrency Pool Server let us know and we will list your website here.
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: 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.
Follow the build/install instructions for your coin daemon. Your coin.conf file should end up looking something like this:
daemon=1
rpcuser=litecoinrpc
rpcpassword=securepassword
rpcport=19332
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:
Clone the repository and run npm install
for all the dependencies to be installed:
git clone https://github.com/AoD-Technologies/cryptocurrency-pool-server.git
cd cryptocurrency-pool-server
npm install
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:
{
/* Specifies the level of log output verbosity. Anything more severe than the level specified
will also be logged. */
"logLevel": "debug", //or "warning", "error"
/* By default the server logs to console and gives pretty colors. If you direct that output to a
log file then disable this feature to avoid nasty characters in your log file. */
"logColors": true,
/* The server CLI (command-line interface) will listen for commands on this port. For example,
blocknotify messages are sent to the server through this. */
"cliPort": 17117,
/* By default 'forks' is set to "auto" which will spawn one process/fork/worker for each CPU
core in your system. Each of these workers will run a separate instance of your pool(s),
and the kernel will load balance miners using these forks. Optionally, the 'forks' field
can be a number for how many forks will be spawned. */
"clustering": {
"enabled": true,
"forks": "auto"
},
/* Pool config file will inherit these default values if they are not set. */
"defaultPoolConfigs": {
/* Poll RPC daemons for new blocks every this many milliseconds. */
"blockRefreshInterval": 1000,
/* If no new blocks are available for this many seconds update and rebroadcast job. */
"jobRebroadcastTimeout": 55,
/* Disconnect workers that haven't submitted shares for this many seconds. */
"connectionTimeout": 600,
/* (For MPOS mode) Store the block hashes for shares that aren't block candidates. */
"emitInvalidBlockHashes": false,
/* This option will only authenticate miners using an address or mining key. */
"validateWorkerUsername": true,
/* Enable for client IP addresses to be detected when using a load balancer with TCP
proxy protocol enabled, such as HAProxy with 'send-proxy' param:
http://haproxy.1wt.eu/download/1.5/doc/configuration.txt */
"tcpProxyProtocol": false,
/* If under low-diff share attack we can ban their IP to reduce system/network load. If
running behind HAProxy be sure to enable 'tcpProxyProtocol', otherwise you'll end up
banning your own IP address (and therefore all workers). */
"banning": {
"enabled": true,
"time": 600, //How many seconds to ban worker for
"invalidPercent": 50, //What percent of invalid shares triggers ban
"checkThreshold": 500, //Perform check when this many shares have been submitted
"purgeInterval": 300 //Every this many seconds clear out the list of old bans
},
/* Used for storing share and block submission data and payment processing. */
"redis": {
"host": "127.0.0.1",
"port": 6379
}
},
/* This is the front-end. Its not finished. When it is finished, this comment will say so. */
"website": {
"enabled": true,
/* If you are using a reverse-proxy like nginx to display the website then set this to
127.0.0.1 to not expose the port. */
"host": "0.0.0.0",
"port": 80,
/* Used for displaying stratum connection data on the Getting Started page. */
"stratumHost": "cryppit.com",
"stats": {
/* Gather stats to broadcast to page viewers and store in redis for historical stats
every this many seconds. */
"updateInterval": 15,
/* How many seconds to hold onto historical stats. Currently set to 24 hours. */
"historicalRetention": 43200,
/* How many seconds worth of shares should be gathered to generate hashrate. */
"hashrateWindow": 300
},
/* Not done yet. */
"adminCenter": {
"enabled": true,
"password": "password"
}
},
/* Redis instance of where to store global portal data such as historical stats, proxy states,
ect.. */
"redis": {
"host": "127.0.0.1",
"port": 6379
},
/* With this switching configuration, you can setup ports that accept miners for work based on
a specific algorithm instead of a specific coin. Miners that connect to these ports are
automatically switched a coin determined by the server. The default coin is the first
configured pool for each algorithm and coin switching can be triggered using the
cli.js script in the scripts folder.
Miners connecting to these switching ports must use their public key in the format of
RIPEMD160(SHA256(public-key)). An address for each type of coin is derived from the miner's
public key, and payments are sent to that address. */
"switching": {
"switch1": {
"enabled": false,
"algorithm": "sha256",
"ports": {
"3333": {
"diff": 10,
"varDiff": {
"minDiff": 16,
"maxDiff": 512,
"targetTime": 15,
"retargetTime": 90,
"variancePercent": 30
}
}
}
},
"switch2": {
"enabled": false,
"algorithm": "scrypt",
"ports": {
"4444": {
"diff": 10,
"varDiff": {
"minDiff": 16,
"maxDiff": 512,
"targetTime": 15,
"retargetTime": 90,
"variancePercent": 30
}
}
}
},
"switch3": {
"enabled": false,
"algorithm": "x11",
"ports": {
"5555": {
"diff": 0.001
}
}
}
},
"profitSwitch": {
"enabled": false,
"updateInterval": 600,
"depth": 0.90,
"usePoloniex": true,
"useCryptsy": true,
"useMintpal": true
}
}
Inside the coins
directory, ensure a json file exists for your coin. If it does not you will have to create it.
Here is an example of the required fields:
{
"name": "Litecoin",
"symbol": "ltc",
"algorithm": "scrypt",
// Coinbase value is what is added to a block when it is mined, set this to your pool name so
// explorers can see which pool mined a particular block.
"coinbase": "Kryptonite",
/* Magic value only required for setting up p2p block notifications. It is found in the daemon
source code as the pchMessageStart variable.
For example, litecoin mainnet magic: http://git.io/Bi8YFw
And for litecoin testnet magic: http://git.io/NXBYJA */
"peerMagic": "fbc0b6db", //optional
"peerMagicTestnet": "fcc1b7dc" //optional
//"txMessages": false, //options - defaults to false
//"mposDiffMultiplier": 256, //options - only for x11 coins in mpos mode
}
For additional documentation how to configure coins and their different algorithms see these instructions.
Take a look at the example json file inside the pool_configs
directory. Rename it to yourcoin.json
and change the
example fields to fit your setup.
Description of options:
{
"enabled": true, //Set this to false and a pool will not be created from this config file
"coin": "litecoin.json", //Reference to coin config file in 'coins' directory
"address": "mi4iBXbBsydtcc5yFmsff2zCFVX4XG7qJc", //Address to where block rewards are given
/* Block rewards go to the configured pool wallet address to later be paid out to miners,
except for a percentage that can go to, for examples, pool operator(s) as pool fees or
or to donations address. Addresses or hashed public keys can be used. Here is an example
of rewards going to the main pool op and a pool co-owner. */
"rewardRecipients": {
"n37vuNFkXfk15uFnGoVyHZ6PYQxppD3QqK": 1.5, //1.5% goes to pool op
"mirj3LtZxbSTharhtXvotqtJXUY7ki5qfx": 0.5 //0.5% goes to a pool co-owner
},
"paymentProcessing": {
"enabled": true,
/* Every this many seconds get submitted blocks from redis, use daemon RPC to check
their confirmation status, if confirmed then get shares from redis that contributed
to block and send out payments. */
"paymentInterval": 30,
/* Minimum number of coins that a miner must earn before sending payment. Typically,
a higher minimum means less transactions fees (you profit more) but miners see
payments less frequently (they dislike). Opposite for a lower minimum payment. */
"minimumPayment": 0.01,
/* 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
be able to confirm blocks or send out payments. */
"daemon": {
"host": "127.0.0.1",
"port": 19332,
"user": "testuser",
"password": "testpass"
}
},
/* 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
optional and will only be used for the ports you configure it for. */
"ports": {
"3032": { //A port for your miners to connect to
"diff": 32, //the pool difficulty for this port
/* Variable difficulty is a feature that will automatically adjust difficulty for
individual miners based on their hashrate in order to lower networking overhead */
"varDiff": {
"minDiff": 8, //Minimum difficulty
"maxDiff": 512, //Network difficulty will be used if it is lower than this
"targetTime": 15, //Try to get 1 share per 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
}
},
"3256": { //Another port for your miners to connect to, this port does not use varDiff
"diff": 256 //The pool difficulty
}
},
/* More than one daemon instances can be setup in case one drops out-of-sync or dies. */
"daemons": [
{ //Main daemon instance
"host": "127.0.0.1",
"port": 19332,
"user": "testuser",
"password": "testpass"
}
],
/* This allows the pool to connect to the daemon as a node peer to receive block updates.
It may be the most efficient way to get block updates (faster than polling, less
intensive than blocknotify script). It requires the additional field "peerMagic" in
the coin config. */
"p2p": {
"enabled": false,
/* Host for daemon */
"host": "127.0.0.1",
/* Port configured for daemon (this is the actual peer port not RPC port) */
"port": 19333,
/* If your coin daemon is new enough (i.e. not a shitcoin) then it will support a p2p
feature that prevents the daemon from spamming our peer node with unnecessary
transaction data. Assume its supported but if you have problems try disabling it. */
"disableTransactions": true
},
/* Enabled this mode and shares will be inserted into in a MySQL database. You may also want
to use the "emitInvalidBlockHashes" option below if you require it. The config options
"redis" and "paymentProcessing" will be ignored/unused if this is enabled. */
"mposMode": {
"enabled": false,
"host": "127.0.0.1", //MySQL db host
"port": 3306, //MySQL db port
"user": "me", //MySQL db user
"password": "mypass", //MySQL db password
"database": "ltc", //MySQL db database name
/* Checks for valid password in database when miners connect. */
"checkPassword": true,
/* Unregistered workers can automatically be registered (added to database) on stratum
worker authentication if this is true. */
"autoCreateWorker": false
}
}
You can create as many of these pool config files as you want (such as one pool per coin you which to operate). If you are creating multiple pools, ensure that they have unique stratum ports.
For more information on these configuration options see the pool module documentation
config.json
set the port and password for blockNotifyListener
blocknotify
command to use:
node [path to cli.js] [coin name in config] [block hash symbol]
Example: inside dogecoin.conf
add the line
blocknotify=node /opt/cryptocurrency-pool-server/scripts/cli.js blocknotify dogecoin %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.
node init.js
When updating Cryptocurrency Pool Server to the latest version it's important to not only git pull
the latest from this repo, but to also update
the cryptocurrency-stratum-pool
and node-multi-hashing
modules, and any config files that may have been changed.
git pull
to get the latest code.node_modules
directory with rm -r node_modules
.npm install
to force updating/reinstalling of the dependencies.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.To support development of this project feel free to donate :)
AStZjnHVZeeMu6qSefmfFf2hcTrw1D4PTV
1HTNmSPrPzWDXiQKHqGGmwxvWpo92861We
qz37lsgu585sthyvj03wdnylzj697utezs09sqr8s6
RKrEC2DN85DEAVGnPKFMT2kwBop7W8SgtH
16pw6eWNQ543djFGPFhWTupKn6DAFybsYj
3Cc2odLwAPMb8in6DtzYcaz7VteMHCdCWS
XptCKDUpStArP6WriH1EqUFkG7X4EB5QVb
DNvszcyDbQbSJ6aFGXCc4adSXoXjtFSXYs
DEiAhRD6ACGeEHPAhKT4W4WiUN6Q85BK83
LQg8JcRgHUST9D2pD6fXXSCRsF9jD3GdWK
CJRx4ps1B8f3fByneiAg7oycEMtTtbFkG2
Lfe93Y8mC1ueKpHtWw2Kp6APoLQs3GpGpF
RMTcqUJnzSTMZW825eP77yDxhcCuW3xVyy
SZjpJRp5rmD83NmaStVJpn4NkfmwM52Jnw
3KxFSn2hw7G61QyheKLYR5sffR6ErKJNys
RRb1GeiDcbAGMJQrckCcFSnKj9rZDUVJ4y
D5Xzq6edmskQBVHUZuzvCbuAg1f8gPU2bo
znhHi2eiRAQhzekktTqdjDBCeb3L2QkuHjf
t1R3enmEZj8rVsUG19sznLSkCRFFj4vEcVM
Released under the GNU General Public License v3