This is an idea that originally grew on #bitcoin-dev and in PM's between me and marioxcc some time ago. After mentioning it the past few days again on IRC, I thought about writing it out.
The idea is to make a server-less pool that is not controlled by a single individual (or group) like traditional pools are. Everything is done by the mining nodes themselves.
1. The conceptWe combine some ideas from slush's pool and from puddinpop's earlier pool:
- Everyone mines real bitcoin blocks.
- The generation transaction has multiple outputs, one for each participant in the pool.
- Miners do not only report blocks that beat the "real" difficulty, but also those beating only a lower difficulty.
Contrary to centralized pools however, the miners are only connected to eachother. This is done through a secondary p2p network (disconnected from the real bitcoin network). Through this network, they show their low-difficulty blocks to eachother.
Each node maintains a table with how the reward from his blocks should be distributed to other pool members. When miner X sees a (low difficulty) block by miner Y that contains address X as generation transaction output, X updates his own table to increase Y's share. The intent is that this reaches an equilibrium proportional to the hashing speed of all players.
Since one has to decide what the generation transaction outputs are before actually starting to mine, a low-difficulty block is an unfakeable proof that one did intend to distribute gains according the way encoded in the transaction. If Y would stop including X as output, X would notice and can retaliate by removing Y from his own outputs.
2. IssuesThere are some possible issues with this:
- Everyone needs to see all low-difficulty blocks by everyone. This quickly leads to rather high bandwidth usage. One solution is to let miners decide their own (low) target difficulty, and encode that in their blocks as well (it can be stored in the coinbase of the generating transaction, for example). A block with target difficulty D (and hash which matches that difficulty, of course) then counts as D diffculty-1 blocks for the speed estimation.
- Attacks: like all pools, this system is vulnerable to a vandalism attack: a miner is able to just not report a block he found that beats the real difficulty, decreasing the joint income of the whole pool. If people were free to join and leave a P2P pool like described here, this would be very hard to detect. A second possible attack is waiting for a opportune time (where you have earned more than you deserve, which will always happen through statistical variation), leave the pool, and return under a different name.
- Bootstrapping: someone new who joins the pool should be able to bootstrap - get an initial distribution table for his blocks, before anyone in the network is including him in their blocks. One possibility is using measured block frequencies (in general, not just the part mentioning him) of other nodes for this.
3. ImplementationOne possible way of implementing this, is as a patch for bitcoind, with RPC calls:
- updatedist(), which sets a new distribution table and difficulty to be used in the generation transactions used by getwork()
- getwork(), modified to incorporate the distribution table set by updatedist()
- getshares(), returning information about recent blocks found by miners (including low-difficulty ones)
The rest of the implementation is then done in a separate pool client, which connects to bitcoind and uses these calls, as well as connecting to other pool clients and forwarding low-difficulty blocks.
An alternative is to incorporate everything into bitcoind, and possibly even use the bitcoin p2p network itself to communicate with other pool nodes. Initially however, it is probably better to let the communication between pool nodes happen through a simple multiplexing server, which forwards blocks between different nodes, adding some authentication as well.
There are further details that are already worked out as well. I'll write those out later, if there is interest.
PS: thanks to molecular for starting this text.