Permissionless mining.
Continuously audited.
Self-custodial payouts.

Permissionless

Mine what you want. The pool can't deny you payouts for your work done or keep you from mining transactions of your choice.

Continuously audited

Every node keeps the accounts and reaches consensus on them, so all nodes are always checking that everyone is paid correctly.

Self-custodial payouts

Rewards arrive in the block’s coinbase, or as bitcoin from selling your shares, always directly to a key you hold.

  • A share: a real bitcoin block, mined at a lower target
  • A block: the share that met the bitcoin target too, and paid everyone
  • An uncle: honest work off the main chain, paid at a discount

Shares land about every ten seconds, each pointing back at its parent. Every one carries an output its miner owns. The chain, the accounting, and the coinbase payouts run on testnet4 today. The market is what we are building now.

If someone pays you, they decide what they pay you for

DATUM and Stratum V2 let a miner build their own block template, and that is real progress. But both leave the share accounting on a server the pool operates, and that server decides what goes into the payout distribution it hands back to you.

Your freedom to choose transactions is therefore worth exactly what the pool will pay you for it. A pool operator is a company in a jurisdiction, and companies can be put under pressured. A company that is told which transactions it may or may not confirm does not need to reject your template, it simply stops counting your shares towards payout.

The accounting is the lever, so the accounting is where the pressure lands. DATUM and Stratum V2 leave that lever in place.

P2Poolv2 moves the accounting to every node. Each node replicates the share chain, recomputes the PPLNS window, and checks the coinbase your miner works on.

Governments are good at cutting off the heads of centrally controlled networks like Napster, but pure P2P networks like Gnutella and Tor seem to be holding their own.

Satoshi Nakamoto
What each stack decentralises, and what it keeps
DATUM / SV2P2Poolv2
Template constructionCan be decentralisedDecentralised
Share accountingCentralisedDecentralised
PayoutCustodial for small minersCoinbase, plus atomic swaps

What we changed since the first P2Pool

The original P2Pool proved the idea of p2p mining pool and then ran into three problems: orphaned shares increases as the pool scaled, misreporting of hashrate to miners that made miners think the pool was broken, and a coinbase that could only hold so many outputs. With advances in bitcoin and in DAG protocols, we can solve these problems.

A graph, not a linear chain
Shares reference up to three uncles, so work that arrives late or races another share still gets paid instead of being orphaned. An uncle is paid with a 10% discount, the share that references it earns a 10% bonus, and each uncle can be claimed once. More miners fit in the chain, and the pool’s variance drops as they join.
Vardiff for each miner
P2Pool handed every rig the whole pool’s difficulty, which sampled far too slowly to report a small miner’s hashrate honestly. Our Stratum v1 server, written from scratch in Rust, runs per-miner vardiff at a three-second target, the same as CKPool. Your local dashboard shows your rigs; a separate dashboard shows the whole chain.
Shares that carry Script
The share chain has its own UTXOs and its own Script, built on rust-bitcoin. Every share has a share-chain coinbase paying one output to an address you control. You sell that output, and because it is a real UTXO under a real script, the sale settles atomically instead of on a promise.

If you mine

99.9999996%

Chance that two S19 Pros find at least one share within a single two-week difficulty period, counting uncles. Without uncles it is 99.2%. The model assumes P2Poolv2 holds 1% of network hashrate and a share every ten seconds. See the working

That number answers an important question for a small miner has: will I ever land a share here? Land one share in a retarget window and you have something to sell.

  • Run your own node. This is the part that makes the pool worth having: it is only as decentralised as the number of nodes in it. Point a rig at somebody else’s node and you have handed them the say over whether your work reaches the chain, even though the payout still lands on your own key. Your own node keeps you totally in control. Run a node privately to serve your miners, or make a node public so other miners can point hashrate to your node.
  • You get paid one of two ways. If your share of the work puts you among the top N miners for a block, your payout is an output in that block’s coinbase. If it does not, you can sell your share-chain outputs to a market maker for bitcoin instead. Either way the payment goes straight to a key you hold.
  • Bring two addresses. Your bitcoin address is where a coinbase payout lands. Your P2Poolv2 address owns the share-chain coinbase, which is the asset you sell. Neither is derived from the other, and the share chain runs the exact same script validation as bitcoin.
  • Set it from your miner’s password field. Put p2p=<your p2pool address> first in the password field so firmware that truncates long passwords still leaves a valid address. If you run your own node, set the address once in config.toml and leave the miners alone.
  • Watch it in Grafana. The node exposes Prometheus metrics at /metrics, with dashboards for per-rig hashrate, chain-wide hashrate by miner, effort into the current block, and coinbase distribution. View our public node's Grafana.

How a share becomes bitcoin

Payout scalability was a big problem face by the original P2Pool. Bitmain’s firmware caps how many outputs a coinbase transaction can carry, which capped how many miners the original P2Pool could pay, and thus capped the variance it could absorb.

P2Poolv2 pays the top N miners from the coinbase and gives every other miner a share-chain output instead. Market makers buy those outputs for bitcoin and receives the reward for the share the original miner was due.

The trade is facilitated using an HTLC. An output on the share chain is atomically swapped for a payment on bitcoin.

That bitcoin half can be a Lightning invoice or an Ark VHTLC. Both settle in seconds and both carry the same hash lock, so the share chain sees the same swap either way.

  1. Alice sets the lock

    The miner picks a 32-byte preimage and asks to be paid under its hash: a BOLT11 or BOLT12 invoice on Lightning, or a VHTLC on Ark.

  2. Alice locks her shares

    She locks her share-chain outputs in an HTLC under the same payment hash, so only the preimage releases them.

  3. Bob checks both sides

    The market maker confirms the share HTLC is final and that the hash in it matches the hash he is being asked to pay under.

  4. Bob pays

    Settling on either rail reveals the preimage to him. That is the whole trick: paying is what unlocks the shares.

  5. Bob claims the shares

    He spends the HTLC on the share chain with the preimage. If he never pays, Alice refunds herself after the timeout, or they both sign an instant refund.

The trading window

A share-chain coinbase matures after about a day of share blocks, for the reason bitcoin makes you wait: it stops a miner selling shares and then reorganising them away. The window closes when the PPLNS window moves past that depth, because the share stops counting toward the next payout. Between those two edges the output is tradable, which makes the output itself a hashrate option that can be traded.

Run a node

A node of your own is what makes you independent. You will need a bitcoin node the P2Poolv2 node can talk to. Use the docker signet if you would rather not point anything real at it yet, or watch the testnet4 pool first to see what a running chain looks like.

The README on the repo has detailed setup instructions

# build and run against your own bitcoind
$ git clone https://github.com/p2poolv2/p2poolv2
$ cd p2poolv2
$ just run

# or bring up a local signet with bitcoind and a miner
$ cd docker && docker compose build
$ ./run-p2pool.sh signet bitcoind
# point a rig at the node
url      stratum+tcp://<your-node>:3333
user     <your bitcoin address>
password p2p=<your p2pool address>

Share addresses are bech32m: p2pool1 on mainnet, tp2pool1 on testnet4, and sp2pool1 on signet.

Before you start

Read the docs

The documentation at docs.p2poolv2.org goes further than this page. It covers setting up a node, the design of the share chain, and each way a share can be paid out.

Where the code is today

P2Poolv2 runs on testnet4. We want to make sure we ready for mainnet with thorough testing on testnet4 first.

Working now

  • Private and public nodes, with the share chain replicating between them
  • Stratum v1 server with per-miner vardiff
  • PPLNS accounting and payouts built into the coinbase
  • Grafana dashboards for local rigs and for the whole chain, published for the running pool
  • A block explorer over the share chain, on the CLI and in the dashboard

Being built

  • Share trading: the HTLC scripts, and the swap flow over Lightning and Ark
  • A terminal app to drive bitcoind, the node, and a Lightning node together
  • The testnet4 fork that resets difficulty so a few Bitaxes can keep the chain moving
  • Wallet support for share-chain outputs

Watch it run: the testnet4 chain explorer shows the tip, the shares, and who mined them, and the pool metrics show hashrate and effort into the current block.

Come help with the pool design on our Matrix chat, or take something off the project board to help build the pool.