Replay Protection in The Blockchain Wars
First, I’ll let Jimmy Song explain transaction replay attacks:
However what this short video doesn’t cover, is that there are multiple levels of replay protection. I believe a lot of anger and confusion stems from not properly understanding this. So I’ll do my best to explain.
Levels of Replay Protection
I believe there are four levels of protection that can be offered in the event of a hard-fork.
- Forced replay protection. After the fork, users have coins on both sides. Whenever they make a transaction, they have to choose which side to send it on. When your goal is to create an alt coin, this makes perfect sense. It’s used by Bitcoin Cash.
- Opt-out replay protection: when a user makes a transaction, by default it is only accepted on one side of the fork. The user can choose to send it on the other side of the fork. This makes sense if you want there to be one chain eventually, but you only want users to switch with explicit consent. This seems to be what the Spoonnet proposals are aiming for (as well as a longer timeline and several useful upgrades). It’s like how the European Union adds new members.
- Opt-in replay protection: by default a transaction is accepted on both sides of the fork. It is a fork of conquest. It makes sense if you have control over a large portion of liquidity and wallet users, and you want those users on your side of the fork from the get go.
- No replay protection. This is every man for themselves, e.g. through mixing coinbase transactions, as Jimmy mentions in the video. Like (3) this gives some advantage to the side with the most initial momentum.
There are various technical ways to implement any of these four levels. The debate gets really confused when arguments about technical feasibility are confused with arguments about which level of protection is desirable.
Solutions can be implemented by just the forking side, or just the remaining side, or both. People often have strong opinions on who should do what. This adds even more confusion.
Finally, developers on one side can write code that’s used on the other side. Or the organizers on one side can offer to include code written by the other side, but refuse to write it themselves. This adds even more confusion.
Mechanims for opt-in Replay Protection
I’d like to zoom in on opt-in replay protection here, because this seems the more likely route for the SegWit2x team to take, and preferable to scenario (4) which is what their currently released software will do. I also find it very interesting.
Bitcoin transactions need to be valid in order to be included in a block. There is a subset of valid transactions which is called standard. By default wallets do not produce non-standard transactions and by default nodes and miners don’t include them in blocks. But if they do end up in a block, it’s not a problem, because they are valid. If however you include an invalid transaction in a block, that block will be rejected. It leads to a hard fork if enough miners mine on top of it regardless.
The SegWit soft fork took advantage of standard-ness to make the upgrade process safe. This ingredient is combined with valid-ness to offer replay protection.
When you write software for a hardfork, you can choose to make previously invalid transactions valid. This appears to be an absolutely necessary ingredient. It’s why Jimmy points out Core can’t add proper replay protection without a (rushed) hard fork. So why is it that?
The key to opt-in replay protection is this:
- by default, use transactions that are standard on the original chain
- define a transaction type that is valid but non-standard on the original chain. Make this transaction type invalid on the new chain.
- define a transaction type that is invalid on the original chain, and make this valid on the new chain.
By default wallets craft transactions of type (1). These are broadcast on both chains. It crafts a transaction of type (2) in order to broadcast on the original chain only. It crafts a transaction of type (3) in order to broadcast on the new chain only.
To take advantage of opt-in replay protection does require a wallet upgrade. It also needs to connect to a special node that relays this non-standard transaction and convince miners to accept it (it’s in their interest). Core could make this easier with a new release, following a new SegWit2x release, but it’s not strictly necessary.
Nodes and miners supporting the new chain have to upgrade anyway, so relay won’t be an issue. Wallets supporting the new chain don’t have to upgrade, but they do need to upgrade to support this replay protection.
Wallet providers with a strong opinion on which chain to follow can choose to make this replay protection the default. This makes the behavior of upgraded wallets more predicatable and prevents spam on the other chain as a bonus.
To be clear, the default behavior offers no guarantee to get included on both chains. Depending on fee levels, it might be included on the new chain first and a long time later on the original chain. It could disappear from the mempool for years and suddenly reappear and get confirmed. Coinbase transaction mixing and double spending could mean it never confirms on one side.
Caveats to replay protection:
- it is critical to rely on invalid-ness, not just on non-standard-ness. An attacker can easily get a non-standard transaction mined, so this would create a false sense of security.
- currently the only reason SegWit2x is a hardfork is the block size increase. Adding replay protection means breaking another consensus rule, which adds risk. The biggest risk in my view is long term maintainability. Once Core starts working on Spoonnet, it may be become non-trivial to merge these changes if it clashes with their replay mechanism.
- when dealing with partially validating wallets, there may be scenario’s where the replay protection itself can be used in an attack!
- it’s possible that the SegWit2x team can’t find a safe and sufficiently easy way to achieve opt-in replay protection. At that point they have to choose between no replay protection, a delay to keep looking, or giving up entirely. Opt-out or forced replay protection seems completely out of their scope.
A Geneva Convention?
If blockchains are war, should we agree on a minimum standard of conduct?
My impression from following the SegWit2x mailinglist and Github discussions, is that they are open to opt-in replay protection (3). They even recognise this as important, but not at all cost. Several Core developers have insisted on either (1) or (2), which the SegWit2x team sees as unacceptable. It’s like a conquering army being asked to leave their tanks at the border.
It’s interesting to remember UASF. They took the “blockchains are war” analogy quite seriously and portrayed themselves as a militia. This parody video illustrates it quite well:
The UASF node software relied on lack of replay protection (even lack of wipeout protection, but that’s a different story) to persuade others to join their effort. I pointed this out in another article at the time.
Greg Maxwell called them out on this:
“First do no harm.” We should use the least disruptive mechanisms available, and the BIP148 proposal does not meet that test. To hear some people — non-developers on reddit and such — a few even see the forced orphaning of 148 as a virtue, that it’s punitive for misbehaving miners. I could not not disagree with that perspective anymore strongly.
Thankfully this game of chicken ended safely.
“do no harm” is probably not realistic in the blockchain wars. But perhaps opt-in replay protection can be agreed on as a miminum standard.
This would come with responsiblity on both sides. The aggresor should use the least disruptive mechanism possible to achieve their goal. They should build in such replay protection if at all possible. However, the defending side should also make a reasonable effort to facilitate this, or at least not actively sabotage it. I don’t see signs of such sabotage thankfully. I’ve seen some accusations, but I believe those are misinterpreted.