The collision problem
In its original formulation, the adaptive PoW algorithm (aPoW) requires to add sequence numbers to each transaction. In this way, nodes can verify whether the issuing node had performed an appropriate PoW. The details of the algorithm can be found in this IOTA Café post and in the Coordicide white paper.
Sequence numbers, however, bring up the problem of collisions, where a node creates several different transactions with the same sequence number. While collision detection is trivial for this attack, the damage provoked is not as easy to recover: indeed, an attacker may temporarily exceed its throughput quota, potentially leading to DoS attacks or discrepancy in the nodes’ ledgers. In a few words, this attack may have serious effects to the network.
aPoW without sequence numbers
In this post, we propose to get rid of sequence numbers. In this approach, a transaction is (not uniquely) identified by the pair {ID, timestamp} (the timestamp is in the signed part of the transaction and it declares when the transaction has been created). Our claim is that a node can correctly determine the amount of PoW to compute without the need for sequence numbers.
Let’s consider the following example:
- assume you have 4 transactions labeled 14, 15, 16 and 17 as the PoW they carry. These transactions have been respectively created at time 1, 2, 3 and 4.
- assume the time window has length 5.
- assume that for every transaction in the time window, the algorithm asks to increase the PoW (i.e., \gamma = 1).
Now, you can fall in one of the four following scenarios:
- Transactions are received in the correct order.
- 1st arrival tx 14: PoW needed 14 - OK
- 2nd arrival tx 15: PoW needed 15 - OK
- 3rd arrival tx 16: PoW needed 16 - OK
- 4th arrival tx 17: PoW needed 17 - OK
- Transactions are received in reverse order.
- 1st arrival tx 17: PoW needed 14 - OK (PoW higher than what is needed)
- 2nd arrival tx 16: in this case the PoW needed depends on the timestamp of the tx received. In fact, nodes keep track of all txs sent by each node and sort them accordingly to their timestamp. Since tx 16 has been generated at time 3 (<4), then the PoW needed is still 14 - OK
- 3rd arrival tx 15: same analysis as for the previous case - OK
- 4th arrival tx 14: PoW needed 14 - OK
- Attacker issues txs with invalid PoW.
- In case txs are received, an invalid PoW (i.e., lower than needed) is trivially detectable and invalid txs are immediately dropped.
- Let’s assume that a node receives a tx with PoW equal to the PoW needed. However, the node cannot know (immediately) whether older txs have been issued before the timestamp of such tx, which would make the PoW of the tx not sufficient. In this case, in order not to slow down the network, the node will forward anyway the tx to the next blocks (e.g., congestion control, below max depth criterion, signature validation). In case it receives new txs with older timestamp, then the node will invalidate such a tx.
- Attacker issues two transactions with the same timestamp.
- We will consider these transactions as two different transactions. In order to determine the correct PoW needed, we sort them by tx hash.
Time window choice
The choice of the time window is crucial in the correct functioning of the algorithm. Our claim is that the time window must be kept small for two main reasons:
- Transaction burst can be captured.
- Implementation is easier: faster sorting, smaller buffers.
However, it is fundamental to keep this time window at least larger than the network delay.
Drawback of this approach
While this approach definitely solves the collision problem, it leads to temporary inconsistencies where some txs could bypass, for a short time, the rate control filter. However, the network is able to correctly identify the valid transaction in one network delay time frame. We strongly believe that the damage of this temporary inconsistency is negligible.