A redditor saying the other day that he doesn’t understand the need for avalanche or what actual it solves. This seems to be a common sentiment. In this post I’ll try my best to articulate the problems that we currently have in Bitcoin Cash and how avalanche attempts to solve them. There are two ways avalanche could be used ― pre-consensus and post-consensus ― so I’ll cover both of them in this article.
So what’s the problem? There are two actually ― block propagation and zeroconf.
A lot of people in our community seem to think that block propagation is a solved problem now that we know about block compression algorithms like Graphene. It really isn’t. All of our block propagation algorithms, including Graphene, XThin, Compact Blocks, and XThinner, work by relying on the mempools of various nodes in the network to be in sync with each other.
If every node already has all the transactions in the block, then block propagation just becomes an engineering challenge of transmitting just the bare minimum data necessary to communicate which of the transactions in the mempool are in the block, not the full transactions themselves.
But there are a variety of reasons why mempools can get out of sync, especially as the transaction volume on the network increases. These reasons include:
- Different mempool policies: Nodes have always remained free to select their own mempool policies. Some nodes reject non-standard transactions while others accept them. Some reject transactions with zero fees while others accept them, etc. These differences don’t necessarily cause just a one off difference, instead any chains of unconfirmed transactions built on one of these transactions will be missing from the mempool of the nodes which rejected one of the dependencies.
- Double Spends: When double spends are sent around the same time different nodes end up with a different view of which one was first. Like the above scenario, the difference in mempools is magnified if chains of unconfirmed transactions are built on one or the other.
- High Volume: At very high transaction volumes so many transactions are flooding around the network that nodes can end up with radically different mempools just through normal propagation delays.
So what happens when mempools get out of sync? Well, it means our block compression algorithms don’t work as well, or even not at all, as we need to transmit full transactions with the block since they are not in the mempool.
This was one of the conclusions from the BU Gigablock testnet research. At a sustain throughput of about 100 MB blocks, there were times when the mempools of the various nodes on the network were so far out of sync with each other that the XThin compression algorithm failed to provide any compression at all and nodes ended up transmitting full 100 MB blocks around the network.
And since it can take longer than 10 minutes to propagate a full 100 MB block, this means that the blockchain forked and kept on forking resulting in a complete consensus failure and a total breakdown of the system. You can watch Peter Rizun present the research here. I’ve cued the video up to the relevant part.
How does avalanche help?
As a pre-consensus mechanism avalanche can help keep mempools in sync. There are different ways it could be deployed. At this point we’re still just discussing avalanche and doing research on the best way to do it, but if you were to require that all transactions be subject to avalanche before they are allowed to be mined then you’d end up with all avalanche-aware nodes on the network in consensus about the set of transactions that are allowed to be mined and thus blocks would always propagate at maximum speed as every node would already have the full set of transactions in the block.
We have a solution in the works for improving zeroconf with double spend proofs to prevent fast respend attacks. This is where an attacker broadcasts two double spends around the same time as each other resulting in a non-zero probability that the double spend will get mined. Our double spend proof relay can help merchants detect these double spends and decline the payment.
The one type of double spend attack that is harder to address is the miner bribe. In this scenario an attacker attaches a large transaction fee to the double spend transaction to try to bribe the miner into accepting it. An example I gave in a previous article was of an attacker buying a $4,000 television. He broadcasts the double spend with a $2,000 fee. If any miner accepts the bribe they get $2,000 and the attacker gets a $2,000 discount.
If even a small percentage of miners are willing accept the bribe then zeroconf doesn’t work for anyone as a payment system where you can commit fraud 5–10% of the time would be unusable for most merchants.
And again, Peter Rizun has presented research suggesting that there are miners on the network today that will happily take a bribe to mine your double spend. Thus this is a real problem that we’d like to solve.
How does avalanche help?
By having nodes come to a pre-consensus on which transactions are minable they will necessarily be resolving conflicts between conflicting transactions (double spends) long before the block gets mined. In fact there’s no reason why avalanche cannot approve a transaction in a matter off seconds. Assuming we can do this, any double spends that are broadcast after a payment is accepted will not be minable. This is true even if a majority of miners, or even all miners for that matter, wish to accept a bribe to include a double spend as they can’t go back and reverse a transaction that has already been marked as final by avalanche.
Thus avalanche has the potential to give us the equivalent of near instant confirmations. Or at least as transactions can be approved as fast as network latency will allow.
So what’s the problem?
Going back to the whitepaper it has always been known that Bitcoin (and any POW cryptocurrency) is vulnerable to attack by a malicious party controlling greater than 50% of the network mining power. Bitcoin Cash is in an especially bad position as a minority user of the SHA-256 hashing algorithm as there are a number of large BTC miners who personally own enough mining power to launch an attack against BCH. Even if BCH was using a different mining algorithm and had it’s own unique mining ASICS, there’s always the possibility that a malicious person with enough resources could buy enough mining power to attack the system.
In fact this is exactly what happened to Bitcoin Cash in November. An irrational, malicious actor (Craig Wright) began using his wealth (or more specifically Caliv Ayre’s wealth) to buy up mining ASICs with a publicly stated goal of 51% attacking Bitcoin Cash. Ultimately they were unsuccessful but the defense of Bitcoin Cash came at great cost. And the defense would not have been possible had Craig and Calvin had more resources or were willing to spend more money to carry out the attack.
One of the temporary emergency defense strategies that was put in place was to have network nodes “finalize” blocks after 10 blocks have been built on top of them. Finalization means that the software considers the given block to be final and permanently part of the blockchain. If a 51% attacker were to publish a longer chain that would otherwise have triggered a reorg, the software will ignore this longer chain as it is trying to overwrite a block that has been marked as final.
On the surface finalization sounds like a good idea. Why in the world would we want to keep open the possibility of a deep reorg and a 51% attack if we don’t have to? After all a monetary system can’t function if historical transactions are subject to reversal.
The answer to this has to do with the concept of objectivity. New nodes joining the network, or those coming back from an absence, only have one objective measure to use to determine which of the competing chains they should follow and that is proof-of-work. If existing nodes reject a deep reorg and follow a chain with less cumulative work then new nodes joining the network have no way of knowing this. The result is that new nodes will sync onto the attacker’s chain and existing nodes will follow their own chain resulting in a split network.
There is also some concern that a 51% attacker could exploit a race condition and cause even existing nodes to split with each other though there are possibly techniques that could be deployed to mitigate this type of attack.
How does avalanche help?
Avalanche can allow us to do finalization without opening ourselves up to the problems described above. There is no risk that a 51% attacker could exploit a race condition to split the network as network nodes use avalanche to coordinate which chain they consider valid.
Further, new nodes joining the network can use avalanche to determine which chain everyone else is following and will avoid syncing on to a chain produced by a 51% attacker.
Thus with post-consensus avalanche a 51% attacker cannot perform deep reorgs, or any reorgs at all for that matter. This means that one confirmation would have the same weight as thousands of confirmations in the current system.
Neither could a 51% attacker mine empty blocks and perform a form of denial of service attack on the chain. Mining a chain of empty blocks requires doing one block reorgs and orphaning blocks mined by other miners. Again, since avalanche prevents this it’s not possible. The best an attacker could do is make is so that the 51% of the blocks he personally mines are empty, but the blocks mined by everyone else would obviously not be.
But what about the security of avalanche? It appears we are circumventing the authority of POW in some respects, doesn’t that mean now that the security of the entire system now rests on the security of avalanche? Not really.
If you look at the snowball algorithm in the avalanche paper you’ll notice that a byzantine attacker who has the capability to attack the system can only prevent the finalization of blocks for as long as he keeps up the attack and nothing more. He cannot, for example, cause some nodes to finalize block A and other nodes to finalizing block B and split the network.
All this means is that if the avalanche system gets attacked the network just defaults back to the vanilla Nakamoto Consensus that we’ve been using from day one. Blocks will not be finalized and nodes will follow the most work chain. Once the attack stops, blocks will start being finalized again.
So ultimately layering avalanche on top of POW has the effect of hardening the system against 51% attacks. It has the following security properties:
- An attacker with > 50% of the hashrate but not > the required threshold of byzantine nodes needed to attack avalanche cannot attack Bitcoin Cash.
- An attacker with > the required threshold of byzantine nodes needed to attack avalanche but not > 50% of the mining power cannot attack Bitcoin Cash.
- Only an attacker who is able to control both the majority of mining power and enough byzantine nodes to overwhelm the avalanche system can attack Bitcoin Cash.
Hopefully this article clears up some misconceptions about avalanche. We still have more work to do to figure out exactly how best to use avalanche in both the pre and post-consensus cases, but it does seem like a promising solution to some of the more intractable problems that have existed since Bitcoin’s inception.