Pooled mining in bitcoin contributes to miner centralization. P2Pool is one solution but has bad scalability; additional hashers require the coinbase transaction to be larger, bigger miners joining increase the variance of payouts for everyone else, and smaller miners must pay extra to consolidate dust payouts. In this email I propose an improved scheme using payment channels which would allow far more individual hashers to mine on p2pool and result in a much lower payout variance.
== Intro ==
P2Pool is a decentralized pool that works by creating a P2P network of hashers. These hashers work on a chain of shares similar to Bitcoin's blockchain. Each hasher works on a block that includes payouts to the previous shares' owners and the node itself. The point of pooling is to reduce the variance of payout, even though on average the reward is the same (or less with fees). The demand for insurance, and the liquid markets for options show that variance does have costs that people are willing to pay to avoid.
Here is an example of a p2pool coinbase transaction:
https://blockchain.info/tx/d1a1e125ed332483b6e8e2f128581efc397582fe4c950dc48fadbc0ea4008022It is 5803 bytes in size, which at a fee rate of 350 sat/b is worth 0.02031050 btc of block space that p2pool cannot sell to any other transaction. As bitcoin inflation goes down and miners are funded more by fees, this puts p2pool at more and more of a disadvantage compared to trusted-third-party mining pools.
As each hasher is paid to their own bitcoin address, this limits the number of hashers taking part as adding more individual people to the payout transaction increases its size. Also small payouts cost a disproportionate amount in miner fees to actually spend, which hurts small miners who are essential to a decentralized mining ecosystem.
This could maybe be solved by keeping a separate balance state for each user that is independent from the payouts, and make payouts only when that balance state exceeds some reasonable threshold. But this increases the variance which goes against the aim of pooled mining.
== Payment Channels ==
P2pool's problems described above come from the fact that it's payout uses on-chain payments. We know the blockchain doesn't scale so it's natural to look for off-chain solutions.
What's needed is a way to use off-chain payments where any number of payments can be sent to each individual hasher without using the blockchain. Then all the parameters of p2pool can be modified to drastically reduce the payout variance. The N of the pay-per-last-N-shares (PPLNS) of p2pool can be increased to something like 6-12 months of shares and so as long as a small miner can mine a share every few months they will always get a payout when p2pool finds a block. The payment channels would be in a hub-and-spokes system and would work in a similar way to coinswap, lightning network, atomic cross-chain swaps or any other contract involving hashlocks and timelocks.
There would still be a sharechain but with hashers paying the entire block reward to a hub. This hub would have a one-way payment channel open to every hasher in p2pool and there would be created a situation where if the hub gets paid then the hashers cannot fail to get paid. Because cheating is impossible, the hub and hashers will agree to just release the money to each other without resorting to the blockchain.
The coinbase address scriptPubKey where block rewards are paid to would be this:
2of2 multisig of hub + successful hasher
OR
hub pubkey + H(X)
A 2of2 multisig between the hub and the "successful" hasher which found the block, although with a hashlock and timelock. H(X) is a hash value, where the preimage X is a randomly-generated nonce which is kept secret by the hub, but X must be revealed if the hub spends via that execution path.
Each payment channel between the hub and a hasher is a 2of2 multisig between them.
The hashers mine a sharechain, a solved share contains the hashers pubkey. The hub keeps up with the sharechain and announces partially-signed transactions going to each hasher. The transactions are updated states of the payment channel, they pay money to each hasher in proportion to the work that the hasher contributed to the sharechain.
This is the form of an updated state of the payment channel:
2of2 multisig UTXO ----> [total - balance btc] hub-pubkey
----> [balance btc] hasher-pubkey + H(X)
If broadcasted, this transaction would allow the hasher to take the balance of the payment channel but only if it knows the value of X.
If a hasher is successful and finds a share that is also a valid bitcoin block, they broadcast it to the network.
Now, the hub can spend the block reward money on its own but only by revealing X. Each hasher could then take that X and combine it with the updated state transaction to get their money. So if the hub gets paid then the hashers cannot fail to get paid. Since defecting is pointless, the hub creates a new partially-signed transaction simply spending the 2of2 multisig output to each hasher, which now does not have any hashlock conditions. A hasher could at any time sign with their own private key and broadcast to get the money settled on the blockchain. After that, the successful hasher signs the 2of2 multisig block reward sending the block reward money to the hub. The successful hasher gets a small bonus via an updated payment channel state for finding the block, to discourage withholding same as today's p2pool. If everything goes well then the hub never reveals X, for mining a new block it announces a new value of H(X).
These payment channels can be kept open indefinitely, as new blocks are found by p2pool the hub creates new updated states with more money going to each hasher. When the hasher wants to stop mining and get the money, they can add their own signature and broadcast the most recent state to the network.
== Hubs ==
The hub is a central point of failure. It cannot steal the money, but if it gets DDOS'd or just becomes evil then the whole thing would stop working. This problem could be mitigated by having a federated system, where there are several hubs to choose from and hashers have payment channels open with each of them. It's worth noting that if someone has a strong botnet they could probably DDOS individual p2pool hashers in the same way they DDOS hubs or even centralized mining pools.
The hub would need to own many bitcoins in order to have payment channels while waiting for blocks to be mined. Maybe 50 times the block reward which today would be about 650 bitcoins. The hub should receive a small percentage of each block reward to provide them with an incentive, we know from JoinMarket that this percentage will probably be around 0.1% or less for large amounts of bitcoin. Prospostive hub operators should write their bids on a forum somewhere and have their details added to some list on github. Hashers should have an interface for blacklisting, whitelisting, lowering and raising priority for certain hubs in case the hub operators behave badly.
As well as the smart contract, there are iterated prisoner's dilemma effects between the hub and the hashers. If the hub cooperates it can expect to make a predictable low-risk income from its held bitcoins for a long time to come, if it does something bad then the hashers can easily call off the deal. The hub operator will require a lot of profit in order to burn its reputation and future income stream, and by damaging the bitcoin ecosystem it will have indirectly damaged its own held bitcoins. A fair pricing plan will probably have the hub taking a small percent to start with and then 12 months later that percentage goes up to take into account the hub's improved reputation.
== Transaction Selection ==
All the hashers and hub need to know the exact value of the block reward in advance, this means they must know what the miner fees will be. This is probably the most serious problem with this proposal.
One possible way to solve this is to mine transactions into shares and so use the sharechain to make all the hashers and hubs come to consensus about exactly which transactions they will mine, and so exactly what the total miner fee will be. A problem here is that this consensus mechanism is slow, immediately after a bitcoin block is found all the p2pool hashers will have to wait 30-120 seconds before they know what transactions to mine, so this would make them uncompetitive as a mining operation.
Another way to deal with this is to have the hub just choose all the transactions, announcing the transactions, total miner fee and merkle root for the hashers to mine. This would work but allows the hub to control and censor bitcoin transactions, which mostly defeats the point of p2pool as an improvement to bitcoin miner centralization.
Another way is to have the hashers and hub estimate what the total miner fee value will be. The estimate could start from the median miner fee of the last few blocks, or from the next 1MB of the mempool. The hub would announce all the partially-signed transactions to every hasher, and then periodically (say every 60 seconds) announce updated versions depending on how the mempool changes. Let's analyze what happens if the estimated and actual rewards are different. If the actual block reward is lower than the estimated reward, then the hub can update the payment channel state to slightly lower values to take that into account. The hashers can't use the higher channel state without knowing X. The successful hasher will get their bonus for finding the block which should help in encouraging them to actually sign the hub's payout transaction. If the actual block reward is higher than the estimated reward, the hub would hopefully still update the hasher's payment channel states because of the interated-prisoners-dilemma effects. But if the actual reward is much higher then the hub may find it profitable to burn its reputation and take the money by revealing X, one situation where this might happen is if someone accidentally pays a very high miner fee and a hasher mines it without it being taken into account in the hub's regular payment channel state updates. Apart from that very specific situation, this scheme of estimating the total miner fee should work. Note that hashers can choose which hub to mine for from their federation of hubs, they should avoid mining transactions which make the block reward much higher than the announced payment channel state, this should avoid the problem.
== Some Notes ==
*) Block rewards are locked for 100 blocks before they can be spent, so the cooperative signatures should be exchanged after 100 blocks just in case the block gets made stale/orphaned. While the hashers are waiting for the 100 reward maturity period, they should mine with another hub as the payout.
*) Today's p2pool has a feature for donating to individual hashers, this could be replicated in the payment channel system by having the hashers sign a LN payment code using the same pubkey that appears in the sharechain. Each LN payment code is then donated to in proportion to the work in the sharechain. After p2pool matures there should be an organized social movement asking for donations to the p2pool hashers. The economic majority has an incentive to support decentralized mining, and in the past when the status quo p2pool was bigger then it did receive them, so this is a realistic ask. The UASF movement was successful so we know such social movements are possible. The donation drive should continue until all public centralized mining pools have low hash power.
*) Each hasher should probably be made to pay some bitcoins into the payment channel address too, to stop DOSers locking up all the hub's bitcoins. If the hasher doesn't find a share within some timeout then the hub should close the payment channel. Another way to rate-limit DOS is for the hub to require a solved PoW challenge before opening a channel.
*) Now that we have segwit all these payment channel schemes are much easier to code.
*) The hashers must keep their money locked up in the payment channel for months before enough collects. This could be a problem because some miners don't really want to hold bitcoin long term. I wonder if theres some way to link up these channels to LN so they can sold straight away. They could also use futures contracts to sell the coins today at a discount and actually deliver the coins later when they close the channel. Edit: according to roasbeef such a connection with LN is indeed possible, then hashers would get bitcoins in their LN wallet which would be available for spending immediately. This would work by having bidirectional payment channels between hub and hashers, and the hub having open payment channels with the rest of the network. Then hashers can send their mining income via the hub to anyone in the lightning network
*) In order to stop holdups or ransom, there is an added OP_CSV execution path in the coinbase. The coinbase output actually has this script:
2of2 multisig of hub + successful hasher
OR
hub pubkey + H(X)
OR
successful hasher pubkey + OP_CSV 6 months
Then the hub has a time limit to spending the coinbase and revealing X, if they don't then the successful hasher can steal the entire coinbase after 6 months.
== References ==
*)
https://en.bitcoin.it/wiki/P2Pool how p2pool works
*)
https://bitcointalksearch.org/topic/m.13057899 the scaleability problems of p2pool
*)
https://bitcointalksearch.org/topic/m.20943086 making the PPLNS window longer
*) book: The Evolution of Co-Operation by Robert Axelrod, for explaining iterated prisoner's dilemma effects in detail
Thanks to the p2pool developer veqtrus for reviewing this
This is also posted on the bitcoin dev mailing list:
https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2017-August/014893.html