In the recent discussions around the Bitcoin Core capacity increases plan and blocksize hard forks there’s been a persistent stream of misunderstandings about the safety of soft forks. This is unfortunate, because in reality they’re one of the best tools we have to upgrade the Bitcoin protocol, one that we’ve used succesfully on numerous occasions.
Soft forks add new rules to the protocol, making previously valid blocks invalid.
Hard forks remove rules from the protocol, making previous invalid blocks valid.
Soft Fork Deployment
Let’s first look at how a standard IsSuperMajority() soft fork is deployed, specifically my own BIP65 CHECKLOCKTIMEVERIFY. Basically this added two new rules to the Bitcoin protocol:
Opcode NOP2 is now CHECKLOCKTIMEVERIFY, which fails if you try to spend funds that aren’t old enough.
After 95% of blocks support BIP65, signalled by the version field in the blockheader blocks that don’t support BIP65 are invalid.
This is the situation right after the soft fork triggers:
Blocks from miners who haven’t adopted BIP65 are still produced occasionally - 1/20th of the blocks. Because these blocks are considered invalid by 95% of the hashing power they’re constantly orphaned off the most-work (“longest”) chain. However the miners who haven’t adopted BIP65 still consider all blocks valid, so nearly all the time they build on top of the most-work chain, rather than invalid blocks. Transactions do sometimes get mined in invalid blocks, but they’ll almost never get more than one or two confirmations.
Hard Fork Deployment
Modern Bitcoin has never done an intentional hard fork; Satoshi did a few in the very early days before the concept of a soft fork was developed. So we’ll talk about a hypothetical blocksize hard fork, also triggered by blockheader version:
This time the blocks from miners adopting the fork are considered invalid by the those who haven’t adopted, because the blocks violate existing rules. So the non-adopting miners build on each others blocks, creating two separate chains. There’s no limit to how long the old chain gets; transactions on the old chain can easily get 6+ confirmations even though they’re considered invalid by the majority of hashing power. This is a serious problem! Currently most (all?) SPV wallets don’t even check the block version, so in the above scenario all they see is this:
Are those blocks valid or invalid? Who knows! It depends on whether you happened to connect to nodes that have or have not adopted the new rule. You can of course download new SPV wallet software that explicitly sets a checkpoint for the fork, but until you do that it’s very easy to get ripped off with fake coins.
Soft Forks Trick Old Nodes Into Degraded Security
All forks degrade security, the question is how badly?
The reason why Bitcoin works at all is because users validate blocks and make sure the rules are being followed; every rule that you aren’t validating and the economic majority is validating is a potential attack.
Secondly, all non-malicious forks explicitly signal that fork is happening by changing the block header version. Good node and wallet soft fork uses that version change to warn the user a fork is happening and let them take appropriate action. Of course, there’s a lot of bad wallet software out there that doesn’t do this, but that’s something this community needs to fix. There’s no trickery involved here - if you don’t want to accept blocks that you might not have validated fully, configure your wallet software to shutdown automatically when it detects an upgrade. If it can’t do that, tell the maintainer to fix that!
BIP66’s Deployment Was A Fiasco; Soft Forks Are Dangerous
When BIP66 triggered deployment it happened a majority of the hashing power was doing validationtionless mining. In short, by mining on top of blocks they hadn’t actually validated they got a head start over miners that took the time to validate first. This is significantly more profitable, because until you start mining on top of the latest block you’re wasting your money.
By the time a majority of hashing power had fixed their nodes, and started validating again, the invalid chain was six blocks ahead of the valid chain. This meant that SPV clients could have been tricked into accepting an invalid transaction with six confirmations.
But, as shown above, that’s can easily happen in a hard fork even if everything goes right! Equally, if miners aren’t validating, in a hard fork they can wind up extending an invalid chain too, so there’s no difference there.
In short, during a soft fork, regardless of whether or not your software is upgraded with the new rules, just waiting two or three extra confirmations is pretty safe, so long as the supermajority of miners are validating. That’s not true in a hard fork, and you better upgrade ASAP.
Soft Forks Are Ugly And Make The Codebase Complex
Some changes are in fact impractical to accomplish with a soft fork, but in general the Bitcoin protocol is designed for upgradability. If you look at the historical codebase, Satoshi themselves appears to have realised soft forks were possible after the first release, adding, for instance, ten NOP opcodes that we’ve since used for upgrades. In my own CHECKLOCKTIMEVERIFY making it a soft fork was an obvious decision - the hard fork version of it is a cosmetic change, precisely because it can use one of the NOP’s Satoshi added.
Segregated witnesses is an interesting example: previously we thought adding it had to be done as a hard fork for practical reasons, but Luke-Jr realised it could be cleanly accomplished as a soft fork instead. For Bitcoin Core itself and almost all SPV wallets the implementation difference is trivial. Only in some rare types of SPV usage is there additional complexity (segwit itself includes an unused field for future soft fork upgrades).
Soft Forks Are Undemocratic
An interesting non-technical objection is that because nodes and miners who haven’t adopted the soft fork end up in the main chain anyway, this is a case of a majority undemocratically forcing a minority to adopt new policies. Of course, it’s your choice to use a protocol with this feature! Satoshi could have just as easily written Bitcoin to treat unknown block versions as invalid, but choose not too.
More pragmatically, if 95%+ of the hashing power disagree with what you think the protocol should be, the remaining 5% chain probably isn’t secure anyway. At minimum choosing to still use it should be an explicit choice (and you probably need a new PoW function).