One popular branch of bitcoin theories focuses on ways that miners can gain an advantage over other miners or mining pools. Other than the obvious 51% attack, "selfish mining" is one of the most commonly discussed principles here. Last year, we posted that we had experimented to see if selfish mining could be implemented as easily as was claimed in the literature. We were unable to make any progress in a timely fashion, and computed that we could earn more profit in a kinder way by dedicating the time to other features. Our suspicion that theory is rarely backed up by practice was confirmed when well-connected Core developer Gregory Maxwell (nullc) replied with his surprise that anyone had actually tried selfish mining.
The "officially" proposed version of selfish mining involves mining normally on a coin until a block is found, and then creating a private blockchain that is not published to the main network. The private chain remains ahead of the chain visible to the remainder of the network. In the ideal case, you keep your private chain two blocks longer than the public chain, and publish the second block behind, so that the other miners will always orphan their blocks until they finally gain enough hashpower to catch up. The exact procedure is more complicated, and full detail can be found in the original paper at https://www.cs.cornell.edu/~ie53/public ... ProcFC.pdf.
Earlier this year, the previous operator of a mining pool E-Mailed Chris to threaten him to buy a license to his pool software. We declined because of the tone of his message. He stated that he had licensed his pool to a new owner, that it had relaunched, that he had put older pools like the Wafflepool out of business, and that the pool would now have increased profits (and we would die) because it would overload networks by having a large hashrate suddenly mine long chains of blocks, thus orphaning the blocks of pools that mine one block at a time. He is licensing the software to other pools, which means that the cryptocurrency industry has now entered an era of block withholding. His message caused us to plan countermeasures, and after we were able to return from the weeks spent preparing taxes, we successfully implemented a solution. This solution was deployed to production on Saturday and Chris is now enabling it one coin at a time.
Our first thought was that the best response to his software would be to engage in selfish mining ourselves. However, we quickly discovered that the original selfish mining paper fails to consider that for all coins, even bitcoin, there are other networks available that use the same algorithm. While selfish mining may make that pool more money on specific coin networks, a significant amount of hashpower needs to be continually devoted to those networks to make the process feasible. Otherwise, the competing pools will catch up quickly, and the entire private chain will be a huge loss. Thus, we discovered that the pool operator was indeed telling the truth; he would have to have a huge amount of hashpower to accomplish this task. However, we found that the devotion to keeping the withheld private chain ahead on one coin is almost always outweighed by the opportunity cost of being unable to mine easier coins that occasionally present themselves as more profitable.
While we don't have the exact code that the pool operator is using, our conclusion through our data is that if he implemented selfish mining exactly as it is described in the paper, or even if he simply withholds blocks in some other fashion, he made his software less efficient because they can't switch coins frequently. If they decide in the future to offer litecoin-only or bitcoin-only mining, selfish mining will benefit users of their pool, but mining only litecoins or bitcoins is a losing strategy, because both scrypt and SHA-256 have more profitable coins available. (There are specific factors that favor single-coin mining in rare environments that are out of the scope of this article.)
While we were confident that selfish mining or overloading networks with long strings of blocks could not improve profitability in a multi-coin environment, we continued our research in an attempt to determine if a variant of the technique could be made to work in the real-world multi-coin environment and if it could be made more network-friendly. We arrived at what we have named "orphan bonuses." To see how this works, it is necessary to understand that there are multiple steps in finding blocks:
- A miner discovers a hash that solves a block
- Network latency of up to 100ms in sending the hash to the mining server
- Delay of a few ms while the CPU sends the work to a multiprocessing system to be hashed and receives the result
- If block found, incur delays in processing block and sending block to network
- The block is sent to all connected nodes, which incurs network latency again
- A new block is discovered by another pool
- 100ms required for daemon to notify mining server, for mining server to create work, for mining server to determine which coins are now most profitable, for mining server to send new work, and for network latency in the miner receiving the new work
- After 99ms, the miner, who has not yet received the new work, finds what it doesn't know is an orphaned block
- Miner transmits orphaned block to mining server
- The block is orphaned, so the mining server discards it
In the orphan bonus scheme, we mine the most profitable networks most of the time. When the case above is detected, this coin actually becomes more valuable to mine because the discovery of the next block results in the status of the previous block being switched from orphaned to immature. Instead of mining the next block on top of the block that the network received earliest, we send a work restart to mine on top of our orphaned block if we are going to continue mining this coin. The expected payout of our orphaned block is now equal to the expected payout of the previous block plus the expected payout of the current block, because finding the next block causes the network to reorganize its chain. If this situation occurs again when we find a second block, then the third block is now as valuable as the last three blocks combined.
The coin selection algorithm will now assign proportionally more miners to the coin, even if a difficulty increase or a price decrease in the next block caused the coin to fall down to the bottom of the list. Additionally, the counterintuitive field of statistics allows miners to be paid more because they stand to earn more if this "higher-value" block is found. Of course, the pool assigns the same number of miners to the coin if we would have a high probability of orphaning our own blocks by assigning more (which is currently assumed to be a target of no shorter than 2.7s block time). We abandon this chain of blocks when another pool finds a block of higher height than ours. Then, the profitability of the coin falls to the profitability of the current block.
One would think that mining on top of an orphaned block is as simple as changing the previous block's hash in the next block. In practice, this scheme is not easy to implement because of shortcomings in the daemon code. After much gnashing of teeth, we discovered that the difficulty of a block is actually encoded in the block itself. Since most coins change their difficulty every block, a method was needed to determine what the difficulty of the next block would be. The difficulty of the next block is often dependent upon the time the last block was received, so our block (which has a timestamp different from the other pool's block) results in a different difficulty for the next block.
The coin daemons do not include code to determine the difficulty of the next block. The best alternative RPC call is "getblocktemplate," which returns a "bits" field that indicates the target difficulty of the next block after the other pool's block - but getblocktemplate does not provide a way for the caller to specify which chain to extend. Thus, we wrote code to add a new "getnbits" RPC call, which receives a String (the block hash), and calls the existing functions in the daemon to determine the next difficulty as if the orphaned block were the latest. This call allows us to provide orphan bonuses without having any knowledge of a coin's difficulty adjustment algorithm, as understanding the difficulty algorithm for all 200 coins would be impossible. Chris further expanded upon this feature by writing code to modify the source after cloning to add this function and its dependencies in other files when coins are being added or updated.
Our first block to be reversed from orphaned state was HeisenbergHex block 1865740, visible at https://prohashing.com/explorer/Heisenb ... 13f813772/. The network saw this block as orphaned, but we mined on top of it and this block is now part of the longest chain.
It takes Chris about 30 minutes to modify a daemon, which means that it will take a little over a week (80 hours) of work to get most daemons recompiled. Some of the newer daemons have additional parameters for a "Consensus" object, which breaks compatibility with this solution, but since the number of daemons with that change is small, those will be ignored for now.
In conclusion, selfish mining isn't an effective way to improve profitability unless a pool is willing to devote a significant amount of resources to a single coin. Since all algorithms have other coins available, the "orphan bonus" solution is a better way to increase profitability. Whereas suddenly publishing huge strings of blocks has implications for double-spending, orphan bonus mining is also friendly to networks, because the orphaned blocks are visible to all and transactions that have more than one confirmation are never reversed.
The previous operator of the other mining pool is offering to license his software to multiple owners, which means that selfish mining, or a variant of it, is here to stay. Even owners choosing not to license the software are now required to respond in some way to remain competitive. It will be interesting to see how the widespread introduction of block withholding impacts the industry, and how multiple-coin pools respond with more efficient solutions.