Early blockchain systems tend to have low throughput and correspondingly low bandwidth requirements, with the consensus protocol itself being the bottleneck in their performance. The Bitcoin network, for example, generates only 1MB of blocks every 10 minutes on average, which is negligible in today’s broadband environment.

In recent years, with the development and maturity of a new generation of blockchain such as Conflux, the throughput of blockchain has made a qualitative leap, and network bandwidth has increasingly become a bottleneck limiting the further improvement of blockchain performance. This time, let’s talk about how Conflux optimizes bandwidth usage.

Transaction broadcast is the first step towards consensus on blockchain. Each time a user initiates a transaction, the transaction is sent from the client program to one or more full nodes. After that, all nodes forward the transaction to their neighbor nodes through the point-to-point network, until finally all the full nodes receive the transaction.

The larger the throughput of the blockchain, the more transactions each node needs to forward. Therefore, when the throughput and network bandwidth of the blockchain are in the same order of magnitude, the bandwidth utilization of the transaction forwarding process will directly affect the final throughput performance of the entire blockchain system.

Let’s start with the simplest scenario: every time a full node receives a new transaction, it sends the transaction to all of its neighbors.

According to the scheme above, each node will receive the same transaction from different neighbor nodes for many times, which means that both transaction sending and transaction receiving have multiple redundancy, and the utilization rate of network bandwidth is naturally very low. A 200-byte transaction with eight neighbors per node, for example, would result in about 1.6kB of traffic being sent and 1.6kB of traffic being received per full node — most of which is wasted.

Even Bitcoin, a system with a throughput rate of 7 transactions per second and bandwidth utilization for transaction forwarding that is not a performance bottleneck at all, no longer uses this unoptimized solution.

Bitcoin’s scheme is that when A Bitcoin node A receives the transaction for the first time, it sends the hash of the transaction (32 bytes) to all of its neighbors (except the one that sent it). After receiving the hash value, neighbor B checks whether it has received transactions with the same hash value. If yes, it means that B has received the transaction and does not need to receive it again. If not, B asks A for the full contents of the transaction.

In the above process, the part that sends the transaction hash value is called announcement. The detection of the transaction hash value can ensure that each node only needs to receive the complete transaction content once, avoiding the bandwidth waste caused by repeated transmission of the complete transaction.

But announcement itself also needs to use network bandwidth. A rough calculation shows that each node in the above scheme sends about 250 bytes during the announcement segment, which is much less than 1.6kB, but still exceeds the amount of data needed to forward a transaction.

Our goal is to reduce the amount of data sent in the announcement session to one-eighth of the bitcoin transaction forwarding scheme.

To do this, the simplest way is to shorten the length of the transaction hash for the announcement segment broadcast. In this paper, to distinguish this hash from the 32-byte transaction hash used at the application level (wallet/smart contract), we call the hash of the application level transaction the ID of the transaction, and the short hash used in the announcement part of the Forwarding is called the Forwarding ID of the transaction.

In bitcoin’s scheme, FID is equivalent to ID and is 32 bytes long. If we set FID to the first 4 bytes of the ID value, we can achieve the goal of reducing the amount of data sent.

However, the shorter transaction FID saves bandwidth while also posing security risks. If two different transactions Tx1 and Tx2 have the same transaction FID, a node received the first transaction Tx1, in the neighbor node sent the second transaction Tx2 FID, because of the FID conflict will mistakenly believe that they have received the transaction, thus no longer request Tx2 complete content. This blocks the broadcast of the second transaction Tx2 in the network.

We can calculate the probability of FID conflict of the transaction in detail:

Assuming a transaction generation rate of 6000 transactions per second, each full node receives a transaction FID and compares it to the FID received in the last 5 minutes to determine whether to request the full content of the transaction. Thus, the probability of a transaction’s FID conflicting with an existing transaction’s FID is 6000 * 300/232, which is approximately 0.04%. This means that an average of 2.4 transactions per second cannot be broadcast because of conflicting FID values.

While a collision probability of 0.04% May not seem very high, it’s a normal situation without an attack. Using a specific attack strategy, an attacker can block the broadcast of any transaction, thus achieving the purpose of blocking a specific transaction.

The attack strategy isn’t complicated either: a 4-byte FID has only 232 possible values, or about 4.2 billion. As long as the attacker for each FID value pre-constructed a transaction coexist, and then can be based on the victim broadcast transaction FID value, from their pre-stored 4.2 billion transactions to find the same VALUE of the FID transaction, and grab the victim in front of the send to as many nodes as possible, The node that receives the first transaction sent by the attacker will ignore the victim’s transaction because of the FID conflict. Even if the victim resends another transaction, the attacker has the ability to repeat the process.

Based on probability calculations, an attacker would have to try to construct about 100 billion transactions to pick 4.2 billion FID different transactions. For server level cpus, it takes only a week to construct about 100 billion transactions. The storage required for computing is optimized to only 32GB.

Overall, the cost of carrying out these attacks is not very high. But in certain scenarios (such as Fomo3D contracts), blocked trades can be costly for victims. So that risk must be eliminated from the outset.

In the next article, we’ll show you how to address the risk of malicious blocking of transactions by switching from static to dynamic FID.