Preventing double spends during network splits

logical clocks and commitments solve the majority of conflicts. However, there are a small number of conflicts which require a more exotic conflict resolution system. These conflicts bring forth a new component of Radix, ‘mass’.

Network splits and double spends

We have previously analyzed the threat of network splits and double spends to distributed networks. Being able to resist such attacks, which aren’t necessarily always deliberate or malicious, is a prerequisite of a functioning network. As a reminder:

Network splits : A network split can see entire geographic regions disconnected from the wider network. In the case of Bitcoin, a malicious actor would split from the main chain in a bid to outpace the block creation rate of the main network and thus overtake and become the main chain itself.

A network split in Radix would similarly involve the creation of two independently operating networks (a mainnet and a subnet). A user able to access both networks during this period could spend on the subnet and then subsequently also on the mainnet. When the two networks merged back together, the subnet would have earlier logical clock proofs than the mainnet and as such the mainnet transaction would be reversed and discarded. This is a subnet attack.

Double spend : A double spend is when the same output is spent twice, such as in the above. This can be malicious and done on purpose to steal from another user, or it can be by accident (e.g. creating the same transaction twice by mistake).

Why is our simple conflict resolution not enough?

The previous article looked at simple conflict resolution works when all nodes are on the same network and therefore we can easily establish a causal history. However, when a portion of nodes are no longer on the same network - as in the case of a network split attack - this will no longer work because:

  1. Nodes won’t have seen the same set of event activity, as the gossip that usually propagates all events would have been operating on the two different networks with no crossover. Instead of our previously structured gossip (which gave us a causal history based off the predictable propagation of information across the network) we find ourselves with two independent and conflicting sets of histories seen by different sets of nodes

  2. The network would therefore have to expend significant resources to establish a single causal history of all of these ‘new’ transactions to work out the correct order, an effort which would be time-consuming. This delay would lead to further attack vectors for a malicious actor to exploit

As such, we need a new means to quickly and fairly resolve these more exotic conflicts.

What is Mass?

We label events within the network (such as messages or transactions) as ‘atoms’. These atoms carry mass if they are transferring value, for example transactions or payloads with fees. This mass is calculated in a very simple manner, simply being the quantity (e.g. the amount of Radix being transferred) multiplied by the amount of time it has been static for. For example, if I transferred 10 Radix to Bob which I had held for 10 days then the mass of the atom being sent would be 100. If I had 5 Radix but had held for 20 days then the mass would similarly be 100.

The first node in the temporal proof for a valid transaction receives this mass. Nodes then build up mass across the multiple transactions they validate. The record of this mass is stored by nodes serving the same shards as said recipient node, as they store temporal proofs from completed transactions (known as finality). It is important to remember that transactions don’t just have a single gossip path through the network but rather have multiple routes due to the nature of our gossip protocol, which sees nodes ‘talk’ to all of their neighbouring nodes. This means that transactions are seen by a large majority of nodes.

This mass allows us to resolve conflicts which cannot be solved by simple resolution by letting us use mass as the determining factor. We add up the mass of all nodes involved in the temporal proof for the conflicting transactions and the atom with the most total mass associated with it is accepted. The losing transaction is meanwhile discarded.

Expanding upon this logically, in the event of a network split whichever network has the greatest mass is the mainnet. The mainnet then absorbs all non-conflicting transactions (i.e. anything that doesn’t constitute a double spend) into it. Conflicting transactions are, again, discarded. This works because although both transactions will have reached finality on their respective networks, the transaction on the mainnet will possess the mass of this large majority of nodes involved in validating it, meaning it will sum greater than the subnet.

Increasing the cost and difficulty of attacks

For conflicting transactions on the subnet to ‘win’, the malicious actor would have to outrace the naturally much larger mass of the mainnet. This is both difficult and expensive and can be thought of as similar as to how Bitcoin or other Proof of Work networks resolve splits – whichever chain has the higher hashrate and thus the greater amount of mined blocks becomes the primary chain, with the other(s) discarded.

The obvious issue would be that someone could ‘fake’ mass on the subnet. However, this is impractical. Whereas hashrate can be increased by purchasing more mining equipment, mass in Radix is partially decided by the unbuyable commodity of time. Even if a malicious actor was to repeatedly spam their own nodes, the mass of each event would be low because the calculation of mass includes time held.

Equally, a malicious actor trying to acquire more Radix to make more transactions would find such a pursuit prohibitively expensive, even for the most well-resourced of actors, as they either have to lock up funds for extensive periods of time (over which time the total mass of the network continues to increase naturally) or they must get a very, very large number of funds and try and spam the network at a slow but continuous rate. This both eats away at the balance in fees, and the network continues to gather mass naturally, creating a very difficult to beat mass race condition.

Finally, whereas a Bitcoin network split would require miners to re-process the transactions lost from the smaller chain, Radix re-merges all non-conflicting transactions automatically. This makes it more suitable for use cases which may rely upon intermittent network connection (e.g. payments on an airplane or in rural areas).

As a result, the majority network should always have the most mass and thus will remain the mainnet, thwarting split attempts, whilst honest transactions remain unencumbered and intact. This is how Radix protects against the network split and double spend attack vectors. Our next article will look at how nodes operate on the network and how we avoid other potential threats such as Eclipse attacks.

What about actions in smart contracts, how do you calculate “mass” in this case. In other words, how radix prevents conflicting actions in smart contracts created by bad actors. Thanks.