Setting up a Pool¶
Expectations¶
- General knowledge of Linux
- General knowledge of git
- General knowledge of networking
- General knowledge of blockchain
- Access to at least 6 machines running Ubuntu 18.04 LTS or 20.04 LTS, to deploy the following services.
- Machine 1: PKT node
- Machine 2: Master, Paymaker & Blkhander
- Machine 3: AnnHandler
- Machine 4: AnnHandler
- Machine 5: BlkMiner
- Machine 6: BlkMiner
Note: It can be done all on a single machine, you just need to pay attention to ports etc. As of June 2022, the network difficulty is high, and given that half of the work is done at pool premises, it's recommended to run at least a dozen BlkMiner machines, with a significant (768GB recommended) ammount of RAM.
Block mining & running a pool¶
Starting your own pool requires setting up a number of services:
- pktd node (one or more) - One pktd instance is required for the Master to function, each of the Block Handlers may optionally use separate pktd nodes.
- Master (one) - This node coordinates all of the others and provides work files and configuration
- Ann Handler (two or more) - These are nodes which accept announcements from the announcement miners in the network, they also provide announcements to the block miners. As you scale up the amount of bandwidth in the pool, you will need to add more Ann handlers.
- Block Miner (two or more) - These high performance nodes download announcements from the announcement handlers and use them in the mining process to mine blocks.
- Block Handlers (one or more) - These nodes receive "block shares" from the block miners and submit blocks if they validate the share
- Paymaker (one) - This node receives updates from the Ann Handlers and Block Handlers and keeps track of who should be paid. The Paymaker sends configuration to the pktd node which is used by the Master in order to make the pool pay out the announcement and block miners
General Information¶
Repository Information:¶
The following repositories hold the required programs to run a pool:
Repository | Tools |
---|---|
packetcrypt_rs: https://github.com/cjdelisle/packetcrypt_rs | AnnHandler, Blkminer, AnnMiner |
PacketCrypt: https://github.com/cjdelisle/PacketCrypt/ | Master, Paymaker, BlkHandler |
pktd: https://github.com/pkt-cash/pktd | pktd |
Assumed network Ranges:¶
In this guide we have two separate networks, the public network (198.51.100.0/24), and local network (10.0.16.0/24) to connect AnnHandlers and BlkMiner.
Machine | Public Network IP | Private Network IP |
---|---|---|
Machine 1 | 198.51.100.1 | 10.0.16.1 |
Machine 2 | 198.51.100.2 | 10.0.16.2 |
Machine 3 | 198.51.100.3 | 10.0.16.3 |
Machine 4 | 198.51.100.4 | 10.0.16.4 |
Machine 5 | X | 10.0.16.5 |
Machine 6 | X | 10.0.16.6 |
Assumed Port Ranges:¶
Service | Machine | Port/Port Ranges |
---|---|---|
Master | Machine 2 | 8080 |
Paymaker | Machine 2 | 8081 |
BlkHandlers | Machine 2 | 8100-8200 |
AnnHandlers | Machine 3 & 4 | 80 |
Installation¶
Machine 1¶
PKTD node:¶
150GB of storage is required at a minimum to run the pktd node. Recommended size is around 250GB of NVMe storage.
- Install Golang
sudo add-apt-repository ppa:longsleep/golang-backports
sudo apt update
sudo apt install golang-go
- Install git
sudo apt install git
- Install the pktd node
git clone --branch develop https://github.com/pkt-cash/pktd
cd pktd
./do
The output should show the following:
Everything looks good - use ./bin/pktd to launch
Machine 2¶
Master | Paymaker | BlkHandler:¶
- Install the required tools:
cd ~
sudo add-apt-repository universe
sudo apt install git
sudo apt install make
sudo apt install npm
sudo npm cache clean -f
sudo npm install -g n
sudo n stable
Restart your shell ### Add here how to get latest stable version of node
- Clone the source code:
git clone --branch master https://github.com/cjdelisle/PacketCrypt
- Build the PacketCrypt code
cd PacketCrypt
npm install
Machine 4 - 6¶
BlkMiner | AnnHandler | AnnMiner:¶
- Install the Required tools:
sudo apt install gcc git
sudo apt install curl
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
- Clone packetcrypt_rs
git clone --branch develop https://github.com/cjdelisle/packetcrypt_rs
- Compile PacketCrypt
cd packetcrypt_rs
~/.cargo/bin/cargo build --release --features jemalloc
Config of pool.js¶
Information:
- pool.js is located at:
~/PacketCrypt/pool.example.js
- You need to edit this file, then run:
cp ~/PacketCrypt/pool.example.js ~/PacketCrypt/pool.js
config.privateSeed¶
Signing of announcements is rarely used, it breaks people mining into multiple pools, and you should set it to null unless "you know what you're doing"
This seed is used for deriving keys which will be used for signing announcements.
Setting this value to an alphanumeric value e.g
oHk8TXpbtRRZGtaYYMnIFAzYMrVh6vA8XzKWWXcKbzCThuFLIJ234bHN5peddQFzR2TtQyo58gcFRP7bKg9BeXZirSqp9gVpjBWp
In general, this value should be set to the null, as signing announcements is rarely used, and breaks Announcement mining with multiple pools if you have your pool externally accessable, and should only be set if you have a strong understanding and knowledge of what you are doing.
config.privateSeed = null
If you aren't bothered by, or don't require your announcements to be signed .
config.paymakerHttpPasswd¶
Anyone who has this password can make http posts to the paymaker (claim that shares were won) You should make this random and also firewall the paymaker from the public. The upload will be done using Authorization Basic with a username of "x" and this as the password
config.paymakerHttpPasswd = 'anyone with this password can post results to the paymaker';
You can put the paymaker behind an http proxy if you wish.
config.masterUrl¶
This is used by the paymaker and block handler when running them with pool.js, it is used to resolve where the master is.
You can either set this as a locally host or put your master behind a nginx proxy
config.masterUrl = 'http://localhost:8080';
or if you have your instance public, and you want to have it be resolvable publically, replace the url with your own.
config.masterUrl = 'http://pool.pktpool.io';
config.rpc¶
The username and password set here, should be the same username and password used at the end of this guide for when you configure the pktd service.
user: 'x',
pass: 'x',
config.annHandlers¶
Information:
- config.annHandlers is a list of json object, with an object for each individual annhandler you would like to run, each ann handler will require it's own individual port.
- As the AnnHandler will be run on the same machine as the BlkMiner you need to make sure there are no over-lapping port bindings.
- If you plan to allow external AnnMiners (AnnMiners not on your LAN to mine against your pool, the url's placed in the AnnHandlers list, should be externally resolvable.
The address that is advertized for accessing this ann handler (external address)
If running locally use:
url: 'http://10.0.16.3:8081','http://10.0.16.4:8081'
If allowing external annminers use a resolved address such as:
url: 'http://ann1.pktpool.io','http://ann2.pktpool.io'
Replace the url with your own.
config.blkHandlers¶
Information:
- config.blkHandlers is a list of json object, with an object for each individual annhandler you would like to run, each ann handler will require it's own individual port.
- BlockHandlers are low-effort high-volume single-threaded workers.
What address should be advertized for accessing this BlkHander, again make sure there are no overlapping ports.
If you are wanting to support external blockminers, this address should be externally resolvable
url: 'http://localhost:8100',
This is the port that the blkHandler will bind to.
port: 8082,
This is the host that the blkHandler will bind to.
host: '::',
This is how many requests a blkHandler can queue before the handler starts rejecting requests
maxConnections: 50,
root: config
config.master¶
Which port to run the master on
port: 8080,
What address to bind to, set to localhost if proxying
host: '::',
Minimum work for an announcement. This number is effectively a bandwidth divisor, every time you double this number you will reduce your bandwidth by a factor of two.
annMinWork: Util.annWorkToTarget(128),
Average number of shares per block, reducing this number will reduce load on your block handlers, but increasing it will allow payment to be spread more evenly between block miners.
This wants to be set to a higher number than one, for the purpose of constantly testing that the block miners are making valid shares. You may have a block miner sitting for hours without a share and then when it wins one, it can become invalid because of misconfiguration
shareWorkDivisor: 4,
Which versions of announcements we will accept
annVersions: [1],
Request that ann miners mine announcements that are this many blocks old.
Announcements contain a commitment of the most recent block hash but they need 3 blocks to "mature" before they can be used
The point of this is so that PacketCrypt is about bandwidth, not latency.
But there is a risk: If there is a surge then you are going to be starved for announcements
When you are starved, you will have few usable anns which causes a slow-down in mining and the announcements which are being submitted are not usable.
When you win a few blocks, those announcements become usable and you surge, which causes you to go back into starvation again.
This should be set to either:
- 0 Which means the announcements you are receiving are used instantly
- 3 Which means you are waiting for the announcements to mature before using them.
If running your own AnnMiners, it is advisable to set this to 0, and add the --mineold 3
to some of your AnnMiner startups on the CLI.
This helps to keep a balance between keeping your pool as powerful as possible, along with having AnnMiners to help out in the case of a starvation
mineOldAnns: 0,
config.payMaker¶
How the miners should access the paymaker (external address), replace the url with your own.
url: 'pool.pktpool.io',
Which port to run the paymaker on
port: 8081,
What address to bind to, set to localhost if proxying
host: '::',
Seconds between sending updates to pktd. If this set to zero, the payMaker will accept log uploads but will not send any changes of payout data to pktd.
updateCycle: 120,
updateCycle: 0
to disable
How many seconds backward to keep history in memory
historyDepth: 60 * 60 * 24 * 30,
Maximum number of simultanious connections to accept before sending 500 errors
maxConnections: 200,
annCompressor¶
Store data in 1 minute aggregations
timespanMs: 1000 * 60,
Allow data to be submitted to any of the last 10 aggregations
slotsToKeepEvents: 10,
What fraction of the payout to pay to block miners (the rest will be paid to ann miners) (Pay per last N shares)
blockPayoutFraction: 0.5,
What percent of the total winnings should be taken for pool management
poolFee: 0.40,
The address which should be paid the pool fee
poolFeeAddress: "pkt1qyc9dkhca7uc84zn3vlgd0h0fxr3twwn34qgeqe",
This constant will affect how far back into history we pay our announcement miners (Pay per last N shares)
pplnsAnnConstantX: 0.125,
This constant will affect how far back into history we pay our block miners (Pay per last N shares)
pplnsBlkConstantX: 2,
When there are not enough shares to fairly spread out the winnings, pay what is left over to this address.
defaultAddress: "pkt1q6hqsqhqdgqfd8t3xwgceulu7k9d9w5t2amath0qxyfjlvl3s3u4sjza2g2",
When something goes wrong, direct pktd to send all coins here, if this is different from the defaultAddress then it is possible to account for and pay out to the miners later when the problem is fixed.
errorAddress: "pkt1q6hqsqhqdgqfd8t3xwgceulu7k9d9w5t2amath0qxyfjlvl3s3u4sjza2g2",
Config of pool.toml¶
Information:
- pool.example.toml is located at: ~/packetcrypt_rs/pool.example.toml
- You need to edit this file, then run: ~/packetcrypt_rs/pool.example.toml ~/packetcrypt_rs/pool.toml
Password used by your paymaker to post logs for payment, the same as config.paymakerHttpPasswd
paymaker_http_password = "you'll want this to be a secret"
URL of the pool master, used for getting configuration and work, the same as: Replace the url with your own.
master_url = "http://pool.pktpool.io"
ann_handler.ah*¶
You can have multiple ann_handlers, you can do this by defining each one such as:
[ann_handler.ah0]
"parameters"
[ann_handler.ah1]
"parameters"
These can all be in a single file to be used by each annhandler, when starting the annhandlers, you would start them with on each respective machine:
packetcrypt ah --config /path/to/config.toml ah0
packetcrypt ah --config /path/to/config.toml ah1
Number of threads to dedicate to the AnnHandler
num_workers = 8
Length of the input queue, keeping this low will create back-pressure and prevent miners from posting too many announcements when the server is in fact overloaded
input_queue_len = 256
The public url of the annhandler, this should match what is set in your pool.js Replace the url with your own.
public_url = "http://ann1.pktpool.io/submit"
Bind to this port
bind_port = "198.51.100.3:80"
Bind this port to the sprayer component
bind_pvt = "10.0.16.3:6666"
Set sprayer
spray_at = ["239.0.1.1:6667"]
spray_workers = 8
For Machine 3 you should end up with something like this
[ann_handler.ah0]
block_miner_passwd = "no one steals my anns"
skip_check_chance = 0
num_workers = 8
input_queue_len = 512
public_url = "http://ann1.pktpool.io/submit"
bind_pub = "198.51.100.3:80"
bind_pvt = "10.0.16.3:6666"
spray_at = ["239.0.1.1:6667"]
spray_workers = 8
subscribe_to = []
files_to_keep = 512
The same logic should be followed for Machine 4 and other handlers you may have.
NOTE: To bind low ports with non-root user run:¶
sudo setcap CAP_NET_BIND_SERVICE=+eip $(which packetcrypt)
Running Manually¶
Machine 1¶
Information:
- These tasks need to be run in the order they are presented
- PKTD needs to have downloaded the full chain first, you will know when the node is upto date when height is equal to the current block on the explorer It can take 12+ hours to fully sync to the current block height
PKTD¶
--rpcuser
and --rpcpass
should match the values set in pool.js under config.rpc
./pktd/bin/pktd --rpcuser=XXX --rpcpass=XXX --miningaddr <your PKT wallet address>
Machine 2¶
Master¶
node ./pool.js --master
Paymaker¶
node ./pool.js --payMaker
BlkHandler(s)¶
Launch the BlkHandler nodes, specify --blk0
for the first BlkHandler, --blk1
for the second, and so forth
cd PacketCrypt
node ./pool.js --blk0
node ./pool.js --blk1
Machine 3¶
AnnHandler¶
cd packetcrypt_rs
./target/release/packetcrypt ah --config /path/to/pool.toml ah0
Machine 4¶
AnnHandler¶
cd packetcrypt_rs
./targer/release/packetcrypt ah --config /path/to/pool.toml ah1
Machine 5 and 6¶
BlkMiner¶
--threads
is the number of threads you want to dedicate to the Blkminer, the default is to use all available threads.
--paymentaddr
is the wallet you want your coins to be mined into, it is advisable to not use the electrum wallet for this.
--memorysizemb
is how much RAM you are allocating to block mining, Ideally you want to set as much as you can.
<Master address of pool>
is the masterUrl of your pool
cd packetcrypt_rs
./target/release/packetcrypt blk <Master Address of Pool> --paymentaddr <your PKT wallet address> --threads 80 --memorysizemb 665000 --handlerpass NoOneStealsMyAnns --subscribe 10.0.16.3:6666 --bind 0.0.0.0:6667 --mcast 239.0.1.1
NGINX Setup (For allowing external AnnMining)¶
Machine 2¶
Update system and install Nginx
sudo apt update
sudo apt install nginx
Unlink default nginx site
unlink /etc/nginx/sites-enabled/default
cd /etc/nginx/sites-available
Create and edit the reverse-proxy.conf file
vim reverse-proxy.conf
The config for the services:
server {
listen 80;
listen [::]:80;
server_name <masterURL>;
location / {
proxy_pass http://localhost:8080/;
}
}
server {
listen 80;
listen [::]:80;
server_name paymaker.pktpool.io;
location / {
proxy_pass http://localhost:8081/;
}
}
Link new file to sites-enabled
ln -s /etc/nginx/sites-available/reverse-proxy.conf /etc/nginx/sites-enabled/reverse-proxy.conf
Remove default config
rm default
Check reverse proxy config is correct
nginx -t
Reload nginx to pick up config changes.
sudo systemctl reload nginx