Tl;dr: Every block in Nano contains a small Proof-of-Work (PoW) that is used to discourage spam. When a block contains a proof with a value below the threshold, it is discarded by nodes in the network. If the proof is valid, then the block is processed.
The term PoW was coined in 1999 though the concept behind it dates from a 1993 journal article. It was initially designed to combat email spam, forcing the sender to incur a computational burden in order to have its email not be immediately rejected by servers. In theory, scaling this computation to a large number of emails (the case of spam) would be impractical.
PoW was largely popularized by Bitcoin, the first decentralized cryptocurrency network. Its purpose is to prevent double-spending by having miners compete for the solution of a [nowadays] very difficult math problem that requires a large number of blind attempts to complete.
There are several PoW functions available to use. For cryptocurrencies, the ones of interest can be categorized in two schemes:
- CPU-bound, where faster processors (or graphics processors) can more quickly obtain the proof.
- Memory-bound, where the computation speed is bound by memory latency or bandwidth, which is expected to not evolve as quickly as processor speed.
In Nano, PoW is used only to discourage spam transactions. Without it, and given the asynchronous nature of Nano’s block lattice, anyone would be able to push valid transactions to the network at a theoretically infinite rate, which would quickly saturate nodes in terms of bandwidth and other resources.
As such, and as we saw in a previous Nano How, every block must contain a small proof.
A commonly asked question is “Why do receive blocks require PoW?”. While the complete answer is more complex than what we intend to go on, it has been discussed in detail. Basically, it is used to discourage from creating high depth forks in the network.
How it works
The ideal proof of work is a mathematical problem that is really hard to calculate but simple to verify.
- Generating PoW — To generate the PoW, the system cycles through the same calculation with slightly different numbers each time, until it gets an answer above the required threshold. This process can take millions of attempts, consuming time and resources.
- Verifying — Verifying the proof is a very quick process. The value of the proof is calculated and checked against a predefined difficulty threshold. When a block contains a proof with a value below the threshold, it is discarded by nodes in the network. If the proof is valid, then the block is processed.
Nano currently uses blake2b as its PoW hash function, a CPU-bound algorithm, due to it being very fast to verify. It is noteworthy that this could change in the future should a more appropriate solution present itself.
In order to enforce a new PoW for every block, the equation that the proof must satisfy depends on the previous block’s hash, as follows:
In this equation:
- nonce is a random 64-bit value which is changed in order to try achieve a valid proof
- threshold is predefined in Nano with the value
As the equation depends on the previous block, there is the special case of the first block (open block) of any account, in which the account’s public key is used instead (read the first Nano How).
While generating a proof requires, on average, 67108864 nonces to be tried (hence the same number of hashes), in order to verify a proof only a single blake2b hash is performed. This means that if it takes one second, on average, to obtain a proof, it will take 14.9 nanoseconds to verify it (assuming it doesn’t take any time to start, which is a crude approximation).
Dynamic and Prioritized PoW
Up until version 18 (Dolphin) of the Nano node, all blocks were treated equally, in the sense that they were processed in a random order or in the order that they arrived. However, in cases of a large transaction rate in the network, nodes might get a great amount of blocks in their processing queue.
In the upcoming version 19 (Solidus), if the network becomes congested then blocks will start to be prioritized by the value of their PoW. Essentially, this means that in the case of network congestion, anyone can have their transaction be prioritized (e.g. if it’s urgent) by computing a higher value proof. It is simple to achieve this effect, as only the threshold has to be changed (to a higher value) when generating the PoW.
The intended effect with Dynamic PoW is to further discourage spamming the network. The most effective spam, currently, is pre-generating blocks and proofs, then pushing all of them to the network at the same time. In this event, the nodes in the network will quickly find that the block processing queues get saturated. By using prioritized PoW, non-attackers will still be able to transact at normal speeds by generating a larger value proof. Note that the attacker can’t change the value of their proof in this kind of spam, as they have already pre-generated all blocks and proofs.
Casual users of the Nano network can spend additional time pre-computing their next PoW so that their transactions are prioritised, while larger services can use auxiliary services such as DPoW to quickly provide PoW on demand for their transactions.