Skip to content
atori.tech

3.1 P2Pool

P2Pool is a decentralized Monero mining pool by SChernykh. It runs next to monerod, builds block templates from your own node, and gives your miners a local stratum server to connect to.

Requirements

  • 2.1 Monero node fully synced, with zmq-pub=tcp://127.0.0.1:18083 in monerod.conf (already part of the 2.1 config)
  • About 1 GB of free RAM
  • A Monero wallet to receive payouts: its primary address (starting with 4), and optionally a subaddress (starting with 8)

Use a separate wallet for mining

Your payout address is public on the P2Pool sidechain, and anyone can see what it earns. Create a dedicated wallet just for mining instead of reusing your main one. P2Pool always needs the wallet's primary address. To get paid to a subaddress of it instead, give both (see Configuration). Integrated addresses don't work.

Preparations

sudo adduser --disabled-password --comment "" p2pool
sudo mkdir -p /data/p2pool/api
sudo chown -R p2pool:p2pool /data/p2pool

Installation

cd /tmp
VERSION=4.18.1

Download

wget https://github.com/SChernykh/p2pool/releases/download/v$VERSION/p2pool-v$VERSION-linux-x64.tar.gz
wget https://github.com/SChernykh/p2pool/releases/download/v$VERSION/sha256sums.txt.asc

Verify

Download SChernykh's signing key, import it and check its fingerprint:

curl -fsS -o schernykh.asc https://keys.openpgp.org/vks/v1/by-fingerprint/1FCAAB4D3DC3310D16CBD508C47F82B54DA87ADF
gpg --import schernykh.asc
gpg --fingerprint 1FCAAB4D3DC3310D16CBD508C47F82B54DA87ADF

Expected fingerprint: 1FCA AB4D 3DC3 310D 16CB D508 C47F 82B5 4DA8 7ADF

Verify the signed checksum file:

gpg --verify sha256sums.txt.asc

Look for Good signature from "SChernykh <sergey.v.chernykh@gmail.com>".

Compare the archive's hash with the signed one. The two hashes printed must be identical:

grep -A2 "p2pool-v$VERSION-linux-x64.tar.gz" sha256sums.txt.asc | grep SHA256
sha256sum p2pool-v$VERSION-linux-x64.tar.gz

Install

tar -xzf p2pool-v$VERSION-linux-x64.tar.gz
sudo install -m 0755 -o root -g root -t /usr/local/bin p2pool-v$VERSION-linux-x64/p2pool
p2pool --version
rm -rf /tmp/p2pool-* /tmp/sha256sums.txt.asc /tmp/schernykh.asc

Choose a sidechain

P2Pool runs three sidechains. Pick one based on your total hashrate, so you find shares often enough to be paid regularly:

Sidechain Flag P2P port Best for
main (none) 37889 Large farms, more than ~50 kH/s
mini --mini 37888 Most home miners, ~5–50 kH/s
nano --nano 37890 A single PC or laptop, under ~5 kH/s

This guide uses mini. Swap the flag and port if you pick another.

Configuration

Store your payout address in an environment file:

sudo nano /data/p2pool/p2pool.env
WALLET=4YOUR_PRIMARY_MINING_ADDRESS
Get paid to a subaddress

Add the subaddress to the same file:

SUBADDRESS=8YOUR_SUBADDRESS_OF_THAT_WALLET
and add --subaddress ${SUBADDRESS} to the ExecStart line in the service below, right after --wallet ${WALLET}. The subaddress must belong to the same wallet as the primary address.

sudo chown p2pool:p2pool /data/p2pool/p2pool.env
sudo chmod 640 /data/p2pool/p2pool.env

Autostart on boot

sudo nano /etc/systemd/system/p2pool.service
# MoneroBox: systemd unit for P2Pool
# /etc/systemd/system/p2pool.service

[Unit]
Description=P2Pool decentralized Monero mining pool
Requires=monerod.service
After=monerod.service

[Service]
User=p2pool
Group=p2pool
Type=simple
WorkingDirectory=/data/p2pool
EnvironmentFile=/data/p2pool/p2pool.env
ExecStart=/usr/local/bin/p2pool \
  --host 127.0.0.1 \
  --rpc-port 18081 \
  --zmq-port 18083 \
  --wallet ${WALLET} \
  --mini \
  --stratum 0.0.0.0:3333 \
  --p2p 127.0.0.1:37888 \
  --data-api /data/p2pool/api \
  --local-api \
  --no-upnp \
  --loglevel 1
Restart=on-failure
RestartSec=30

# Hardening
PrivateTmp=true
ProtectSystem=full
ProtectHome=true
NoNewPrivileges=true
PrivateDevices=true

[Install]
WantedBy=multi-user.target

--p2p 127.0.0.1:37888 means no incoming sidechain connections: P2Pool connects out to its peers, just like monerod. --no-upnp stops P2Pool from opening ports on your router by itself through UPnP, which it does by default.

sudo systemctl daemon-reload
sudo systemctl enable p2pool

Firewall

Open the stratum port, so your miners on your home network can connect:

sudo ufw allow 3333/tcp comment 'P2Pool stratum'

The sidechain P2P port 37888 needs no rule: P2Pool only listens on 127.0.0.1 for it.

Run

sudo systemctl start p2pool
journalctl -fu p2pool

The first start syncs the sidechain, which takes a few minutes. When it's done you'll see SideChain new chain tip messages every ~10 seconds.

Validation

Check that P2Pool listens on its stratum and P2P ports:

sudo ss -tlnp | grep p2pool
LISTEN 0  128  0.0.0.0:3333   0.0.0.0:*  users:(("p2pool",pid=3456,fd=20))
LISTEN 0  128  127.0.0.1:37888  0.0.0.0:*  users:(("p2pool",pid=3456,fd=19))

P2Pool writes stats to its data API:

jq . /data/p2pool/api/local/stratum   # your miners: hashrate, shares found, connections
jq . /data/p2pool/api/pool/stats      # sidechain: total hashrate, miners, blocks found

When do I get paid?

Once you have at least one share in the PPLNS window (the last 2160 sidechain blocks, about 6 hours), every Monero block that P2Pool finds pays you directly. Payouts appear in your wallet like normal incoming transactions, and unlock after 60 blocks (~2 hours). You can also look up your address on community P2Pool observers, such as p2pool.observer.

Upgrade

Repeat Download, Verify and Install with the new VERSION, then:

sudo systemctl restart p2pool

Extras (optional)

Save 2 GB of RAM with light mode

By default P2Pool keeps the full 2 GB RandomX dataset in memory to check shares quickly. On a node with little RAM, add --light-mode to the ExecStart line. Share checking gets slower, which is fine for a small home setup.

Run P2Pool's P2P traffic through Tor

Your P2Pool node's IP is visible to the other P2Pool peers. To hide it, send its outgoing connections through Tor by adding to ExecStart:

--socks5 127.0.0.1:9050 --socks5-proxy-type tor --no-dns
- --no-dns makes P2Pool skip DNS lookups, so they can't leak outside Tor. - Add --no-clearnet-p2p to connect only to P2Pool peers on Tor, so your traffic never leaves the Tor network through an exit relay. - Expect somewhat higher latency, which can cost a few more stale shares.

This is the outgoing-only setup from P2Pool's own Tor guide.

Troubleshooting

P2Pool exits right after starting

Read the log: sudo journalctl -u p2pool -n 50 --no-pager. Common causes:

  • monerod isn't fully synced yet. Check monerod status first, and start P2Pool once it shows 100%.
  • ZMQ isn't enabled. monerod.conf must contain zmq-pub=tcp://127.0.0.1:18083. After adding it, restart monerod, then P2Pool.
  • Invalid wallet address. It must be the primary address (starting with 4) of a mainnet wallet, with no spaces or quotes in p2pool.env.
My miners are connected, but I never find a share

That's normal at low hashrate on the wrong sidechain. Check jq .hashrate_15m /data/p2pool/api/local/stratum and compare with the table in Choose a sidechain. Under ~5 kH/s, switch to --nano (and P2P port 37890).

Many stale or orphaned shares

Usually network latency or a slow node. Make sure monerod is fully synced and not starved for CPU (check htop while mining on the same machine), and avoid mining over Wi-Fi.

Uninstall

sudo systemctl disable --now p2pool
sudo rm /etc/systemd/system/p2pool.service /usr/local/bin/p2pool
sudo ufw delete allow 3333/tcp
sudo rm -rf /data/p2pool
sudo deluser --remove-home p2pool

Payouts you already received stay in your wallet: they're ordinary Monero transactions.

Port reference

Port Protocol Use
3333 TCP Stratum server, for XMRig on your home network
37888 TCP P2Pool mini sidechain P2P (localhost only; P2Pool connects out)
37889 TCP P2Pool main sidechain P2P (if you use main)
37890 TCP P2Pool nano sidechain P2P (if you use nano)