Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
NANO COMMUNITY DOCUMENTATION, THE MISSING LINK
ATTENTION: This document is not written by an official source, so there may be differences from reality.
This document includes a step-by-step explanation of how the transaction confirmation process works, a protocol-level QA, a few potential features for the future, and some remaining questions for the developers, all summarized from various conversations in the "protocol" Discord channel of Nano.
There are still a few uncertain things, but, leaving aside their effect on Nano's security, their effect on this documentation is small.
This document contains what's missing from the official documentation, and is an addition to, not a replacement for, the:
- Whitepaper: https://raiblocks.net/media/RaiBlocks_Whitepaper__English.pdf
- Official Wiki: https://github.com/nanocurrency/raiblocks/wiki
Third-party documentation regarding the election mechanism can be found at https://github.com/NanoTools/wiki/blob/master/Rebroadcasting-Elections.md
The "TODO" parts are meant for further clarification. They are either unknown or not yet implemented.
Nano is a delegated voting cryptocurrency which uses digital signatures (to prevent forgery), voting (to provide consensus), vote delegation (to provide consensus availability), double spend detection (to maintain ledger integrity), DAG (to chain the blocks), block lattice (to provide ledger integrity starting from the genesis block), peer to peer networking (to balance the network traffic).
Simplistically, Nano's consensus protocol can be thought of as being an m-out-of-n signature scheme, where each signature is weighted by a voting weight.
Nano doesn't use Proof-of-Work for confirming transactions.
When an account A is created, another account is automatically chosen (from a curated list) to be A's delegate; A can later change the delegate.
The delegate is automatically assigned a voting weight equal with the balance of the account A. The sum of the voting weights that are assigned to a delegate from all delegating accounts A is the voting weight of the delegate.
Delegates can choose to be representatives. A representative whose voting weight is at least 0.1% from the maximum voting weight (133 millions) participates in the confirmation of transactions.
To confirm a transaction initiated by A, the system adds together the voting weights of all the representatives that are online, and if the total exceeds a threshold (which is configurable for every node) then the transaction is considered confirmed. Once a transaction is confirmed, it can't be rolled back (TODO: from v17).
If a double spend is detected, the difference between the voting weights received by the blocks linked to the double spend must be over the above threshold in favor of one of the blocks.
In order to ensure that account's A blockchain is not maliciously altered, each transaction (send and receive) made from account A must contain the hash of the previous transaction (made from account A), hash called "root". Each representative has in its database the last transaction of account A, transaction called frontier. When a representative receives a transaction from account A, it checks that its root equals the root from the frontier of account A; if the check fails, the transaction is rejected.
A node treats a transaction as confirmed only if the number of votes (called "confirmation height") of the send block is over the "confirmation quorum" of 50% from the voting weight of the representatives which are online (with a minimum of 45% from the maximum voting weight - 133 millions), so at the minimum, a transaction is confirmed with 22% from the maximum voting weight (133 millions). These are the default values, and can be changed in the configuration of a node's software.
Every transaction that's saved in the local ledger contains the number of votes that it has received so far, in a field called "confirmation height". A user can check to see if the confirmation height is above the quorum. Once a transaction is confirmed, it can't be rolled back (TODO: from v17). TODO: Is the receiver's wallet also waiting for the associated receive block to have the same confirmation quorum?
CONFIRMATION QUORUM CALCULATION
The confirmation quorum is calculated as:
quorum = max( voting weight of online representatives, online_weight_minimum ) * online_weight_quorom / 100
NOTE: A transaction is confirmed when the difference between the voting weights received by two successive blocks (with the same root) exceeds "quorum". If there aren't multiple blocks with the same root, then the single existing block is confirmed if the voting weight that it has received is over "quorum". Since this condition is too complicated to carry throughout this document, the simpler "transaction is confirmed with X% quorum" is used.
You can find "online_weight_minimum" and "online_weight_quorom" in the configuration file of a node's software.
The default values are 60 million votes for "online_weight_minimum", and 50% for "online_weight_quorom". At the minimum, in absolute terms, this makes the default confirmation quorum about 22% from the maximum voting weight (133 millions).
While "online_weight_minimum" can be over the maximum voting weight (133 millions), the calculated confirmation quorum must be achievable, that is, must be below the maximum voting weight (133 millions).
These options allow users to adjust their confirmation expectations based on the risks they face.
Should nodes use an absolute supermajority (65% from the maximum voting weight of 133 millions) confirmation quorum? Ideally, they should use a 100% confirmation quorum. The problem is that some representatives may be offline and unable to vote, so a quorum would not be reached. Some representatives may be offline on purpose, in order to make it impossible for transactions to achieve a quorum. So, the lower the quorum is, the more available it is, but at the same time the more likely it is for a "TWO QUORUMS ATTACK" to succeed. An absolute supermajority is a good balance for large transacted amounts, since an attack would be absurdly expensive, yet the confirmation quorum would be reached fast enough.
There are a few tens of representatives with a voting weight above 0.1% from the maximum voting weight (133 millions), which vote in the overwhelming majority of cases. For the current online voting weight, see https://mynano.ninja/active
Taking into consideration that some of the representatives may sometimes be offline, it's perhaps optimum to set "online_weight_minimum" with the maximum voting weight (133 millions), and "online_weight_quorom" with 60%. Since the confirmation quorum is therefore relative to the maximum voting weight, knocking more representatives offline doesn't affect the security of the confirmation process, only its availability.
The sender sends X nano by creating and signing a send block; the sender's new account balance is included in the block. The send is broadcast through the network.
The receiver receives the send block, validates it, and creates and signs a receive block; the receiver's new account balance is included in the block. In order to create the DAG, the root of the receive block is the hash of the received send block. The receive is broadcast through the network.
As they spread through the network, the blocks (sends and receives) are signed by the representatives, thereby assigning to them their voting weight as (an equal number of) votes.
A block is signed only by the representatives which have a minimum voting weight, else the representatives with smaller voting weights would waste too much network resources by broadcasting their votes. Currently, the required minimum voting weight is 0.1% from the voting weight of the representatives which are online.
A random node receives blocks that are signed by various representatives. The votes of the representatives are not stored because they would take too much space. The voting weights of the signing representatives are accumulated in a field called "confirmation height". If the confirmation height of a transaction exceeds the confirmation quorum, the transaction is considered "confirmed" and is stored in the local ledger (together with the confirmation height). Once a transaction is confirmed, it can't be rolled back (TODO: from v17).
NOTE: A transaction is confirmed when the difference between the voting weights received by two successive blocks (with the same root) exceeds "quorum". If there aren't multiple blocks with the same root, then the single existing block is confirmed if the voting weight that it has received is over "quorum". Since this condition is too complicated to carry throughout this document, the simpler "transaction is confirmed with X% quorum" is used.
TODO: In order to accumulate the voting weight of a representative, the representative's voting weight must be stored for a minimum time in the local ledger. If this time hasn't yet passed, the representative's voting weight which is hardcoded in the wallet is used instead. This ensures that the voting weight is not quickly moved around from representative to representative to make it appear as if there are a lot of representatives (with large voting weights) which have signed a block in good faith.
DOUBLE SPEND DETECTION AND RESOLUTION
A double spend is an attempt to spend an amount of cryptocurrency multiple times in order for the paying account to appear to have a larger / infinite balance.
A double spend is detected when a node receives at least 2 different (signed) blocks which have the same root.
If a sender makes a double spend, the blocks spread through the network and get votes based on which is seen first by the representative nodes. But taken as a whole, the network doesn't know which of the two blocks linked to it has to keep.
Neither block has a majority of votes yet, so the network has to vote on which block to keep. The first created block could end up losing the vote.
When a double spend is detected by a node, the node adds up the votes from the representatives who have signed the blocks linked to the detected double spend, waiting for the votes for a time limit, or until a block exceeds the confirmation quorum.
A double spend resolution means that the node keeps the block (linked to the double spend) which reaches the confirmation quorum. This means that a double spend resolution rolls back unconfirmed transactions (TODO: from v17). TODO: If neither block reaches the confirmation quorum, both blocks are discarded and the node tries to synchronize from the network.
Q: What would happen if a double spend were to occur months later?
A: The second block of the double spend would be rejected because a double spend detection and resolution may happen only within a time limit after the first block is received.
However, if an attacker has acquired enough votes to exceed the confirmation quorum, he can modify its own ledgers and create the future confirmation quorum according to his own ledgers. This is a gameover scenario for any cryptocurrency because a single entity controls the entire quorum (either for confirmation or double spend resolution). The "TWO QUORUMS ATTACK" is cheaper to execute.
Account balances are included in the signed blocks so that a node can store only the last block of each account, with no block history. The block history is eliminated during pruning.
Bootstrapping is when a new / empty node downloads the ledger data locally, so that it can start confirming transactions.
A pruned ledger can be downloaded from any node. In this state, the ledger can't be trusted. A pruned ledger doesn't contain the transaction history, it contains only the last processed block for each account.
When a block is received from the network, its "Previous" field has to match the hash of the last block of the same account which is stored in the local ledger.
The received block must go through the normal confirmation process. The confirmation quorum is verified using the voting weights of the representatives which are hardcoded in the wallet. At this point, the information of the account which has sent the block is trustworthy.
This has a downside: right after the bootstrap, the bootstrapping node can't be immediately certain of the account balances from the downloaded ledger. To be certain, the node must either wait for a new block with the required confirmation quorum, for the desired account, or query the network for the representative votes for the (last) known block of the desired account.
Q: Why is bootstrapping secure considering that the real-time voting weight changes constantly?
A: There will only ever be a few tens of representatives that form the vast majority of the maximum voting weight (133 millions), and these are hardcoded in the wallet. This is because as time passes, fewer nodes will have the necessary resources to handle all the network load.
When nano moves around from account to account, the voting weight moves mostly among these few representatives who are trusted by most of the network, so individual changes to the voting weights don't matter much, at least not enough to be relevant.
It's safe to update (in the wallet) the hardcoded voting weights of the representatives only rarely, like once a week, because in that timeframe, the voting weight just moves among those representatives that you already trust. So, if the voting weights just moves around a bit, why would your trust in the one-week-old voting weights shift a lot?
The hardcoded voting weights will always include the voting weights of the non-official representatives, so even if the voting weights of the official representatives become 0, the wallet will still be able to bootstrap securely based on most of the voting weight possible.
See "SECURELY ACQUIRING THE VOTING WEIGHTS" for a way to make bootstrapping even more secure.
The attacks described below try to exploit a low confirmation quorum, one significantly below the supermajority (65%) from the maximum voting weight (133 millions). See "CONFIRMATION QUORUM CALCULATION" for what the default confirmation quorum is currently, and for recommendations on how to change it.
The "SECURITY FALLBACK ATTACK" also tries to exploit a low quorum, but a double spend resolution quorum rather than a confirmation quorum.
If an absolute supermajority (65% from the maximum voting weight of 133 millions) confirmation quorum is used, the only potential attack that remains is the "TWO QUORUMS ATTACK" because it doesn't depend on a low confirmation quorum.
They are by no means easy to execute, but, still, are possible.
All the attacks are absurdly expensive if both the confirmation quorum and the double spend resolution quorum are at least an absolute supermajority.
The "TWO QUORUMS ATTACK" would be very difficult to execute because the attacker would have to isolate the representatives in two groups, so that each group would receive and sign only one block from a double spend of the attacker.
If the attacker would not isolate the representatives, the representatives would detect the double spend and reject the second block of the double spend, making the attack useless. In the meantime, the first block, the one with the quorum reached, remains valid and is in the ledger of the recipient.
However, for a 50% quorum, all the attacker needs is to isolate the representatives in two groups. The attacker would not need to be invested in Nano (to acquire voting weight). The higher the quorum is above 50%, the more voting weight the attacker would have to control. The attacker's required voting weight is A >= 2 * Q - 100, since he can vote with "A" votes for both blocks of the double spend. So, at 50%, the attacker needs to control 0 voting weight. At 65%, the attacker needs to control 30% of the voting weight (on top of being able to isolate the representatives).
These attacks can be applied to any cryptocurrency which uses voting. The "TWO QUORUMS ATTACK" doesn't require a low confirmation quorum.
Q: What's the short version for potential severe attacks on Nano?
A: A double spend may be performed if an attacker has a voting power over 22% from the maximum voting weight (133 millions), not from the voting weight that's available online, and the attacker has the ability to filter the network traffic of the victim. If the attacker's voting weight is smaller, the attacker must also have the ability to filter the network traffic of the representatives, so that it can split them in two groups that can't communicate with each other.
High risk nodes can virtually eliminate the possibility of a such an attack by setting their confirmation quorum to an absolute supermajority (65% from the maximum voting weight of 133 millions); see the recommendations from the "CONFIRMATION QUORUM CALCULATION". See the "TWO QUORUMS ATTACK" to understand why this should be done.
Unlike cryptocurrencies which have a single global ledger, in Nano each node has its own ledger.
Because the network (both Internet and Nano) is working asynchronously, the ledgers can differ significantly among the nodes, and can present unreconcilable accounting realities to their users and to the nodes which bootstrap from them. This is known as a split ledger.
To understand a ledger split, consider a shop which treats a block as confirmed, but a double spend occurs afterward and the representatives choose to keep the other block of the double spend. This can happen, for example, if the shop's node gets disconnected from the network before it detects the double spend. At that point, the ledger is split between the shop and the representatives.
After such a moment, the representatives would not sign a send block from the accounts linked to the double spend because they have a different frontier for those accounts. The only way for the shop to continue to use its account is to discard its ledger and bootstrap from a ledger that the representatives use. But this means discarding the last payment(s) received by the shop.
The ledger split affects only the accounts linked to a double spend (not all the accounts in the ledger), including those that are indirectly linked to the double spend (by receiving the spends with a confirmation quorum less than an absolute supermajority). The accounts that were linked to the double spend would have to discard their ledgers and download them from elsewhere, by bootstrapping from other nodes. However, doing so means losing their known account balances, which may mean that some financial losses may be incurred by the users who have relied on these nodes for transaction confirmations.
A ledger split matters most if it affects the representatives. A representative ledger split can occur if the representatives are split in 2 groups during a "TWO QUORUMS ATTACK", and a double spend is performed.
In the case of a ledger split, a representative should never bootstrap the entire ledger, but only the affected accountchains. This is because there may have been in the past another double spend to an account which has waited for an absolute supermajority (65%) confirmation quorum. Obviously, if the entire ledger were to be bootstrapped, that spend that waited for an absolute supermajority would be lost as well, and if the representative which performs the bootstrap has enough voting weight, it might become impossible for the the account (which has waited for an absolute supermajority) to ever receive again an absolute supermajority confirmation quorum.
In order to minimize the possibility of ledger splits, the confirmation quorum should be an absolute supermajority (65% from the maximum voting weight of 133 millions); see the recommendations from the "CONFIRMATION QUORUM CALCULATION". See the "TWO QUORUMS ATTACK" to understand why this should be done.
Nano isn't resilient to malicious network partitioning (see "TWO QUORUMS ATTACK") because the default confirmation quorum is much smaller than the supermajority (65%) from the maximum voting weight (133 millions).
Nano is resilient to accidental / non-malicious network partitioning so long as an account doesn't (accidentally) spend in multiple partitions, or receive with a confirmation quorum less than an absolute supermajority (from an account that has spend in multiple partitions). Since a node (which manages an account) is in a single partition, it can't spend by accident in multiple partitions.
(Bitcoin is also not resilient to malicious network partitioning.)
If an account were to spend in multiple partitions, its frontier and that of the receiver (if received with a confirmation quorum less than an absolute supermajority) would no longer match among the partitions, so their accountchains would remain split after the partitions merge.
This means that if conflicting transactions (like a double spend) occur in multiple partitions (see "TWO QUORUMS ATTACK"), once the partitions join together, the network can't resolve the conflicts and a ledger split occurs, which means that the account that has spent (or received) in multiple partitions can't be used anymore. For details about a ledger split, see the "LEDGER SPLIT".
Since in Nano each account has its own chain, a split in one accountchain doesn't affect the rest of the ledger.
A node which requires a high level of security, can set its confirmation quorum to an absolute supermajority (65% from the maximum voting weight of 133 millions); for how to do this, see the recommendations from "CONFIRMATION QUORUM CALCULATION".
Even in the case of waiting for an absolute supermajority, there could still be a ledger split among the representatives (who, by default, don't use an absolute supermajority), and this split will have to be fixed by some representatives by (manually) discarding the frontiers of the accounts that don't match to the rest of the network. This effectively behaves as a rollback and could be theoretically exploited by attackers. However, this type of attack is even more difficult than a "TWO QUORUMS ATTACK". It's still very important for representatives with a large voting weight to be very careful if they ever discard their current ledger and bootstrap again (because the newly boostrapped ledger may be missing some transactions that had an absolute supermajority in the previous ledger).
SOLUTION: Increase the quorum as recommended in the "CONFIRMATION QUORUM CALCULATION", to an absolute supermajority. If a node does this it has a guarantee that a receive will not happen if there is a network partitioning (because the send isn't confirmed), which means that it has a guarantee that the receive isn't linked to a ledger split.
SOLVING LEDGER SPLITS
Q: Let's say that an attacker successfully partitions the representatives in two and double spends in both partitions. What happens when the partitioning ends?
A: When the partitioning ends, the quorum becomes unachievable in the future for the account that has spent in multiple partitions, or has received with a confirmation quorum less than an absolute supermajority, and the split has to be manually solved in the ledgers of enough representatives that can produce the quorum.
To manually solve an accountchain split, due to a malicious partitioning, a revert has to be performed for all the accountchains that were linked to the spends and receives made in multiple partitions. There are several cases:
- Account A has spent to account B, and B has performed a receive (with a confirmation quorum less than an absolute supermajority). In this case no manual revert can be performed. If a revert were performed (for A), this kind of partitioning could be used as a tool to attack any account (B) and force that account to also perform a revert (which would be rather impossible for something like an exchange). In this case, accounts A and B can't be used again. It's not a problem that A can't use his account since he's the attacker, but it's a problem that B can't use his.
- Account A has spent to account B which has received with a confirmation quorum of at least an absolute supermajority. In this case a manual revert may not be performed for A because B would be affected.
- Account A has spent to account B which has not yet received. In this case a manual revert can be performed for A. B is not affected.
This means that a revert may be performed only if there is no associated receive. If a receive was performed with a confirmation quorum of at least an absolute supermajority, only the attacker will be unable to use his account.
Getting involved in a ledger split can be prevented by increasing the confirmation quorum to an absolute supermajority. If a node does this then it has a guarantee that a receive will not happen if there is a network partitioning (because the send isn't confirmed), which means that it has a guarantee that the receive isn't linked to a ledger split.
GENERAL SOLUTION FOR ATTACKS
In order to make all the attacks listed here become absurdly expensive, the confirmation quorum and the double spend resolution quorum must be at least an absolute supermajority (65% from the maximum voting weight of 133 millions). The votes should be coming from several representatives in order to mitigate the effects of hacked representatives.
In the case of a double spend, if a block linked to the double spend had already reached an absolute supermajority when the double spend is detected, it must be kept (not discarded).
The representatives must always use an absolute supermajority confirmation quorum in order to make it absurdly difficult for an attacker to split the ledger (see "TWO QUORUMS ATTACK").
Online services can use an absolute supermajority quorum without visibly affecting the speed of their services because the waiting time would be just a few (tens of) seconds.
Q: Would choosing an absolute supermajority (65%) as the confirmation quorum affect the performance?
A: Practically not at all.
There are two aspects of performance: transactions per second, confirmation time. The first would not be affected at all, but the second would be longer for the transactions which wait for an absolute supermajority.
For small to medium payments there is no need to wait for an absolute supermajority confirmation quorum because a "NETWORK TRAFFIC FILTER ATTACK" would not be profitable for the attacker.
For large payments, an absolute supermajority confirmation quorum can be used without problems because the necessary waiting time would usually be measured in (tens of) seconds. In any case, large payments don't require performance, they require safety.
The only potential issue for an absolute supermajority is the uptime of enough representatives that can form the supermajority quickly enough.
If a node receives large amounts of nano, it may be worthwhile for an attacker to specifically target the node using the "NETWORK TRAFFIC FILTER ATTACK" and "TIMING ATTACKS".
NETWORK TRAFFIC FILTER ATTACK
A double spend detection depends on the good will of the nodes which forward all blocks, and on the good will of the representatives who form the confirmation quorum which is required for a double spend resolution.
Double spend detection can be made useless by performing a targeted attack, regardless of the waiting time involved. The attacker can highjack the network traffic of the victim, since it's not encrypted, and can remove from it all the blocks which can allow the victim to detect a double spend (meaning all the blocks linked to the double spend, except for one), so the victim has no idea of the double spend (and of the fact that other nodes detect the double spend).
An attacker may be able to partly replace the digital reality of a victim node, that is, replace all the honest peers that are directly connected to the victim.
To know that a block linked to a double spend was removed from the network traffic, the victim would have to actively check for a while if a double spend was detected by another trusted node. Performance wise, this would be no better than waiting for a majority confirmation quorum in the first place.
Even the receivers who wait a few minutes to see if they detect a double spend, are still exposed to this attack because they can't receive the blocks which would allow them to detect a double spend. Also, performance wise, they are no better than waiting for a majority confirmation quorum in the first place.
This type of attack can be eliminated by encrypting the blocks, to the same size (to be indistinguishable), but because each node would have to encrypt each block separately for each node from the network (otherwise they can be decrypted by the attacker, since the network is public), the performance penalty would be huge. It's not enough to encrypt only the network traffic between direct peers because the attacker could replace all the direct peers of the victim (since the network is public), and would therefore still be able to filter the traffic.
SOLUTION: A confirmation quorum of at least an absolute supermajority (65% from the maximum voting weight of 133 millions) would make this attack absurdly expensive since the attacker would have to control over 30% from the maximum voting weight (133 millions) in order to execute the "TWO QUORUMS ATTACK".
SECURITY FALLBACK ATTACK (PURPOSEFUL DOUBLE SPEND ATTACK)
A system is only as secure as its weakest link is. Nano is only as secure as the minimum between the confirmation quorum and the double spend resolution quorum because the attacker would target the lower quorum, even if that would mean forcing a double spend.
SOLUTION: Ensure that the confirmation quorum and the double spend resolution quorum are equal.
TWO QUORUMS ATTACK
This attack involves an attacker who double spends to an account he controls and to a victim account.
This attack can work only in combination with a "NETWORK TRAFFIC FILTER ATTACK", where the attacker highjacks the network traffic of the victim, since it's not encrypted, and removes from it whatever blocks he needs to hide from both the in and out traffic. The attacker would also have to highjack the network traffic of all the representatives, effectively splitting the representative voting weight in two equal isolated groups.
In order for this attack to succeed, it's necessary to have A >= 2 * Q - 100, since he can vote with A votes for both blocks of the double spend. "A" is the attacker's voting weight (as percentage from the maximum voting weight of 133 millions), and "Q" is the transaction confirmation quorum (as percentage from the maximum voting weight, which the victim requires in order to consider a transaction as confirmed). This equation is for an ideal case since in reality the voting weight of the representatives isn't perfectly splitable in two.
If this condition is not fulfilled, the attacker can't create two quorums, one for each of the blocks of his double spend.
The attacker must be able to send each of the blocks of his double spend to some representatives which will create a number of votes Q - A, but not to the other representatives (who have to vote for the other block of his double spend). If the representatives see both blocks of the double spend, they would detect the double spend and keep only the block which already has over 50% of the voting weight, block which can arrive at the victim with its quorum reached (the other block will not reach the quorum).
The attacker then creates a number of votes A for each of the blocks of his double spend. The victim and the representatives which voted for the block seen by the victim can see the attacker's A votes for the same block, while the attacker's A votes for the other block can be seen only by the other representatives (and the rest of the network). This way, the attacker has formed two separate quorums and has successfully double spent, tricking the victim into thinking that it has received a valid payment.
To clarify with an example: The quorum is 65% from the voting weight. The attacker controls 30%. The rest of the representatives control 100% - 30% = 70%. The attacker splits the representatives in two groups, each with 70% / 2 = 35%. The attacker votes together with each group, reaching a total of 35% + 30% = 65% (the quorum).
Once the attacker stops filtering the network traffic, long after the maximum double spend detection period, the ledger is split. Before this split is detected and somehow fixed, the attacker can move the money out of the system.
This attack is far more complex and expensive than a simple "NETWORK TRAFFIC FILTER ATTACK" where the expected quorum is low and where only the blocks which allow the victim to detect a double spend have to be filtered out from the network traffic of the victim.
The higher the victim's expected confirmation quorum is, the more expensive it is to perform this attack. For example, if the quorum were an absolute supermajority (65% from the maximum voting weight of 133 millions), the attacker would have to control over 30% from the maximum voting weight.
Would this attack be lucrative? Probably not, because of its complexity and because it would be too high profile due to the resources involved, but it can be done as a proof of power. Still, there are much simpler and cheaper attacks, like a DDOS.
SOLUTION: A confirmation quorum of at least an absolute supermajority (65% from the maximum voting weight of 133 millions) would make this attack absurdly expensive since the attacker would have to control over 30% from the maximum voting weight (133 millions).
Even if the attacker were to have an absolute supermajority confirmation quorum by himself, he would still have to combine this attack with a "NETWORK TRAFFIC FILTER ATTACK" because otherwise the victim could detect a double spend.
Q: With a confirmation quorum below 50%, does the attacker need a negative voting weight?
A: Below 50% the attacker may be able to create more than 2 quorums, depending on how low the quorum is.
If the quorum is 1% and the attacker has 1%, the number of isolated quorums that the attacker can create is unlimited because he controls the whole quorum, so he can vote differently for every node from the network (presuming he can filter double spend messages from the network traffic of that node).
If the quorum is 5% and the attacker has 1%, the maximum number of quorums that he can create is (100% - 1%) / (5% - 1%) = 24.
ATTACKING AN ABSOLUTE SUPERMAJORITY QUORUM
SUMMARY: This attack is particularly dangerous because it allows an attacker to obtain paid services for free, while no double spend is made, while an absolute supermajority confirmation quorum is used throughout the network, and while the attacker controls no voting weight. This attack can work only if the attacker can filter the network traffic of the representatives.
Even in a voting-based cryptocurrency which uses an absolute supermajority (65% from the maximum voting weight) confirmation quorum, an attacker may still be able to trick a victim into believing that the victim has received a payment, even though the network will not know of the payment in the future (which is equivalent to the victim not receiving the payment).
To perform this attack, the attacker must filter the network traffic of the representatives who have together the absolute supermajority of the voting weight, so that they can vote on a transaction but can't receive votes from other representatives, for that transaction.
This means that the representatives will not be able to confirm the transaction that they've voted for, in their own legers, but the victim node still receives all the votes for the transaction, therefore seeing an absolute supermajority confirmation quorum, and therefore confirming the transaction in its own ledger. At this point, the accountchain known to the victim differs from the same accountchain known to the representatives, making the representatives behave as if the victim has not received the payment, which means that the representatives will not vote on any future sends initiated (by the victim) from that accountchain.
SOLUTION: Let's say that Alice sends some nano to Bob, and Bob uses a supermajority confirmation quorum.
After Bob confirms the transaction, he must send a small amount of nano from his account to some other account.
The representatives will vote on this second transaction only if the root block of the frontier that they have (in their ledgers) for Bob's account is the same as the root block of the frontier of Bob's account which is in Bob's ledger (because this second root block was used by Bob to create the second transaction).
If Bob's send achieves the supermajority quorum, it means that the representatives have voted for it because they know the same history of Bob's account, as Bob knows it, hence, the original payment from Alice to Bob has been stored in their ledgers and is available for the future.
If Bob's send doesn't achieve the supermajority quorum, it means that the representatives have not voted for it because they know a different history of Bob's account, hence, the original payment from Alice to Bob has not been stored in their ledgers. This means that Bob must ignore the original payment from Alice.
This solution could be automated by confirming a receive block with the confirmation rules used for its root send block, and by storing its confirmation state in the ledger (just as it's stored for the send block). The wallets should show that receive blocks are confirmed.
For this solution to work, a node has to be able to vote for a (send / receive) transaction only if the previous (send / receive) transaction for the same account is already confirmed and stored in the local ledger, that is, it works only if performance optimization shortcuts, like pipelining, are not employed.
Timing attacks can occur if transactions are treated as confirmed with a small confirmation quorum, and can be rolled back if a double spend is detected. Nano can no longer have this scenario.
In a timing attack, a victim (exchange or shop) sees a send, says that it's confirmed, and immediately starts providing the service. The victim's node may detect and rollback a double spend immediately afterwards, but this has no effect if the victim's management software isn't listening for double spend detections, or detects them a nanosecond after providing the service.
DOUBLE SPENDS AT EXCHANGES ATTACK
This is a timing attack.
This attack may be possible because the large exchanges allow now (or maybe in the future) very fast deposits and withdrawals, and the time required to detect a double spend may be longer than the attack time.
When distributed exchanges will be a thing, such an attack will be amplified because the trade from a currency to another will happen much faster, and there will be no "verified" exchange accounts to slow the attacker down.
An attacker creates an account on exchanges X and Y.
The attacker deposits nano in the account from exchange X. The attacker double spends the same nano in the form of a deposit in the account from exchange Y.
The attacker exchanges the nano for another currency and withdraws everything, on both exchanges. The attacker has now doubled his money. The double spend detection is useless at this point since the withdrawn currency is not nano, so rolling the blocks back doesn't affect the attacker, but only the exchange for which the deposit was rolled back.
Q: Can Nano be a game changer?
A: Nano can become one of the most widely used cryptocurrencies. Like all the other cryptocurrencies, it's a work in progress and may change as the game changes.
Q: Is Nano's consensus mechanism Proof-of-Stake?
A: The phrase Proof-of-Stake may make people falsely believe that nano coins have to be used as stake.
Nano's consensus mechanism is based on a delegated voting system.
Each account has a voting weight equal with the account balance, but this power is delegated to another account, called representative, and the representative could have a 0 account balance (so no stake in the system, yet it influences consensus). Neither the delegating account, nor the representative lock a stake in the system.
Why does Nano work? Because most of the representatives are honest. This is why, in the beginning, vote-based cryptocurrencies own the consensus-producing nodes / accounts, and they move the voting weight slowly to others, as others show themselves to be honest enough.
Byzantine fault tolerance (see https://en.wikipedia.org/wiki/Byzantine_fault_tolerance ) requires that 2 / 3 of the participants be honest. That's it. It does not require a stake in the system, it does not require incentives.
Q: I've heard that Proof-of-Stake is not secure because of the "Nothing at Stake" principle. In Proof-of-Stake, what ensures that double spends don't occur?
A: Decentralization does, or, in other words, the voting weight held by the honest actors versus the voting weight held by the malicious actors.
A single malicious actor is irrelevant. To break a voting based consensus (like used in Nano), the malicious actors must collude and must together control a minimum percentage from the total voting weight available for consensus; this percentage depends on how secure the system was designed to be.
In order to break a standard Byzantine fault tolerant system, the malicious voting weight must be at least 1 / 3 from the total.
For Nano, this percentage is a difference of 50% between two blocks linked to a double spend (so a distribution like 75% for one block and 25% for the other block), but can't be lower than about 22% from the maximum voting weight (133 millions).
PROOF-OF-STAKE versus PROOF-OF-WORK
Q: Nano's representatives are visible targets for hacking, bribing, coercing, and man-in-the-middle attacks. So, isn't Proof-of-Work more secure than Proof-of-Stake?
A: The listed potential weaknesses of the representatives are just as true for the miners in Proof-of-Work. Miners are visible targets for hacking, bribing, coercing.
In Proof-of-Work, nodes are susceptible to man-in-the-middle attacks because, if an attacker filters the network traffic of victims, the victims see only what the attacker lets them see. This means that the nodes can never know which chain is the longest, and whether this longest chain is honest. Here are some attacks:
- Bitcoin timejacking: http://culubas.blogspot.com/2011/05/timejacking-bitcoin_802.html
- Bitcoin eclipse attack: https://www.usenix.org/system/files/conference/usenixsecurity15/sec15-paper-heilman.pdf ( video: https://www.usenix.org/node/190891 )
- Bitcoin routing attack: https://btc-hijack.ethz.ch/files/btc_hijack.pdf
- Ethereum eclipse attack: https://eprint.iacr.org/2018/236.pdf
(Encrypting the network traffic in a peer-to-peer network doesn't protect the nodes from network traffic filtering because the peers of a node are public, so they can be replaced by the attacker.)
It may be easy for an attacker to obtain over 50% of the hashrate that's necessary to break Proof-of-Work. For details, see https://www.crypto51.app
Proof-of-Work (in general, Bitcoin, in particular) is not resilient to malicious partitioning of the network. See the above "eclipse attack" and "routing attack" for details. See "NETWORK PARTITIONING" for details.
BYZANTINE FAULT TOLERANCE
Q: Is Nano Byzantine fault tolerant?
A: Byzantine fault tolerance means that a system must reach an agreement in the presence of faults that may appear as non-faults, where the faults aren't necessarily the consequence of malicious human action.
You can read about Byzantine fault tolerance at https://en.wikipedia.org/wiki/Byzantine_fault_tolerance and https://medium.com/@alexandratran/a-cursory-introduction-to-byzantine-fault-tolerance-and-alternative-consensus-1155a5594f18
Nano is Byzantine fault tolerant from v17.
Nano, like Bitcoin, isn't resilient to malicious network partitioning. See "NETWORK PARTITIONING" for details.
Q: Isn't decentralized Byzantine fault tolerance possible only in a Proof-of-Work system, not in a Proof-of-Stake system?
In Nano, transactions are confirmed by representatives. The critical thing for a node to know in order to be able to confirm transactions is the distribution of the voting weights of a few tens of representatives. Currently, this list of voting weights is in the wallets, so it's provided by the wallet developers, so it's partly centralized; it's only "partly" because a user can choose from the wallets made by different developers.
The section "DECENTRALIZED VOTING WEIGHTS ACQUISITION" describes a (non-Proof-of-Work) solution for getting this list of voting weights in a decentralized manner, instead of getting them from the wallet. This mechanism makes a decentralized delegated-trust system work, in the absence of Proof-of-Work, at least to the extent that the users have to trust the voting weights from the wallets only the first time they use it. Since the users have to trust the wallet every time they update it, it's perfectly fine to trust once the list of voting weights from the wallet.
In contrast, in Proof-of-Work the user can never know which chain is the longest, and if this longest chain is honest. It may be easy for an attacker to obtain over 50% of the hashrate that's necessary to break Proof-of-Work. For details, see https://www.crypto51.app
The level of decentralization is represented by the degree of difficulty that an organized group encounters in controlling the consensus, that is, the confirmation of transactions. Decentralization is not represented by the number of nodes from a cryptocurrency's network.
In order to quantify the degree of decentralization (D) in a practical way, we need an asymptote that depends on the number of entities that can collude in order to control the consensus. For example, for 1 entity we can have D = 0%, for 2 D = 5%, for 10 D = 50%, for 50 D = 90%, for 100 D = 99%, with the asymptotic limit of 100%.
An asymptote is used because the doubling of a low number of nodes (say from 5 to 10) has a much higher effect on decentralization than the doubling of a high number of nodes (say from 1000 to 2000), because it's much easier to seize control of 5 entities than of 1000.
If a single entity can control the consensus, the currency is not a decentralized cryptocurrency, but a centralized digital currency.
Q: There are tens of thousands of nodes in the Bitcoin network. Does this mean that Bitcoin is highly decentralized?
A: The number of nodes from Bitcoin's network doesn't represent decentralization because it only takes a few of the top miners to control the confirmation quorum (over 50% hashrate). You can see the distribution of the hashrate at https://btc.com/stats/pool ; note that Bitmain controls the BTC.com and AntPool mining pools.
Also consider that most of Bitcoin's miners are in China, so it only takes a single entity, the Chinese government, to control Bitcoin's confirmation quorum.
Some people point out that a Bitcoin mining pool is formed by a large number of participants who are free to switch to another pool any time they want. True, but future choices don't change the current distribution of the control of the confirmation quorum, so this answer is presently correct. A similar freedom, but one which doesn't require mining hardware, to change the representative, is available to all Nano users. This means that the level of decentralization of both Nano and Bitcoin is one thing today, and can can be something else in the future.
VOTING PROTOCOL CHANGES
Q: Do Nano representatives vote on protocol changes, like Bitcoin miners do?
A: Bitcoin miners are signaling, not voting. The difference between signaling and voting is that signaling isn't enforced, it's an indication of what miners what to do; miners endorse a certain action. Voting, like Nano representatives do for transaction confirmation, is enforcing certain actions, by code.
In Nano, there is neither voting nor signaling of protocol changes.
Q: What's the maximum performance of Nano?
A: It's the maximum performance of enough representative nodes which can, at any time, form the confirmation quorum which is required to confirm transactions.
Sharding can, on average, improve performance [number of shards] / 2 times.
Q: Is the performance affected in any way by the worst-equipped and worst-located node?
Transactions are confirmed when the required confirmation quorum is formed by any representatives that are able to handle all the necessary network load. The worst-equipped and worst-located node is irrelevant.
Double spends can be detected by any node. So, again, the worst-equipped and worst-located node is irrelevant.
Q: Can Nano match the scalability of currencies which reach consensus with a small, centralized set of validating nodes?
A: Nano's consensus is achieved by the representatives that can keep up with the transactions and can create a confirmation quorum together. Consensus doesn't wait for nodes to keep up.
If the voting weight gets more distributed, more representatives are needed to achieve the confirmation quorum and this could make consensus slower, but this process is dynamic and decentralized in Nano, it's not an artificial limit like in the centralized currencies.
Q: How is block broadcasting done?
A: The peer-to-peer network is a flood-fill network. Nodes broadcast unseen blocks, that is, all the blocks that other nodes have broadcast. A node doesn't try to send blocks to every other node.
Q: How does the network choose which nodes process the transactions?
A: All nodes process and broadcast transactions to their direct peers, peers which then propagate the blocks further through the entire online network.
Representative nodes sign blocks before broadcasting them, thereby assigning to them their voting weight as (an equal number of) votes.
Q: How are the voting nodes chosen?
A: Users can choose any nodes to represent them during voting. The chosen nodes are called "representatives".
Currently, the official wallet automatically sets the representative of every created account to a representative controlled by the developers. The account owners can then change their representatives at any time.
Q: What do nodes vote on?
A: Non-representative nodes don't vote, they just balance the network traffic and forward all blocks.
Representative nodes whose voting weight is at least 0.1% from the voting weight of the representatives which are online, do vote on any block they receive and on any double spend they detect. Voting on a block is done by validating, signing and broadcasting the block.
Q: Why do representatives exist?
A: For practical reasons. Representatives are nodes that can be and are online (to vote) virtually all the time. Because the number of representatives is limited, the bandwidth usage is also limited.
If every node were to vote, every vote would be propagated through the network in order to reach all the nodes, which means that the bandwidth usage would be huge and the time to confirm a transaction would be much higher.
USE OF NON-REPRESENTATIVE NODES
Q: Is there a reason to run a node which is not a representative?
A: Non-representative nodes don't vote, they just load-balance the network traffic and forward all blocks.
Running a node improves the performance and reliability of the network, so of double spend detections, so it helps maintain the ledger integrity.
However, they also increase the overall network traffic because all the nodes are asking for blocks when bootstrapping and when solving block gaps.
Running a non-representative node allows people to have a local copy of the ledger and not depend on someone else for the information it contains.
Q: Why are receive blocks necessary? If all the other nodes in the network have the signed send block (which can only increase the balance of the receiver), why do they need a confirmation from the receiver?
A: A receive block contains the account balance and the hash of the previous block, and is signed by the account owner. In this way, the network is informed in an authoritative manner about the balance and the chaining of blocks for each account.
Since a receive block must be signed by the account owner, the balance and the last block hash of the account can't be faked by the representatives with a majority of voting weight, hence, the ledger is much more secure. If the receive blocks were not signed by the account owner, the representatives could collude (to achieve the confirmation quorum together) and spend any amount from the account.
The hash of the previous block is used to achieve the chaining of the blocks of an account, the DAG structure. This is because the receive blocks include the hash of the send transaction of the sender account, not the hash of the last send transaction of the recipient account, and this intertwines the blockchains of two accounts, fact which reduces the malleability of the ledger; see https://en.wikipedia.org/wiki/Malleability_(cryptography)
The chaining of the blocks of an account is a crucial requirement of the protocol because it allows any node from the network to see if a newly received block can be processed, or there is something missing in between the newly received block and the last processed block.
The processing of receives is commutative, that is, if there are several pending sends that have to be processed as receives, they may be processed in any order.
Another reason why receive blocks are necessary is described in the "ATTACKING A SUPERMAJORITY QUORUM".
DAG / BLOCK LATTICE
Q: Is the "DAG / block lattice" critical to Nano's security and performance?
A: It's true that Nano's strength comes partly from the DAG / block lattice, but the DAG / block lattice affects its security, not its performance.
The DAG / block lattice is only a piece of the puzzle. It's the way Nano orders transaction in the ledger, so that the malleability of the ledger is minimized. See https://en.wikipedia.org/wiki/Malleability_(cryptography)
This ordering also allows for transactions to be validated up to the genesis block, for individual accounts.
The potential performance of Nano is due to the fact that it doesn't require Proof-of-Work for transaction confirmations, that is, it's security is not based on symmetric cryptographic operations (where a brute-force attack is as expensive as the protection), but on asymmetric ones (where a brute-force attack is exponentially more expensive than the protection). Nano doesn't have block producers (like in Proof-of-Work) to slow its performance.
There is no need for the block lattice in order to have a fast cryptocurrency. You can have a fast (decentralized) cryptocurrency without the block lattice, where the representatives simply do accounting for each account. This is possible because all the representatives have to do is perform addition and subtraction on individual account balances, hence the system can be asynchronous (inter-account) and therefore fast. All that's needed is to ensure that each operation is performed only once (which is easy to do with a counter since transactions are signed).
While in the absence of the block lattice it would not be possible to check an individual account's balance up to the genesis block, it would be possible to replay all transactions up to the genesis block, which would prove that the ledger has started from the genesis.
The biggest problem is that, without the block lattice, the ledger would be less secure since it would be easier for the representatives to collude in order to revert the state of an individual account, because they would only have to revert the state of that account (since the blockchains of the accounts would not be mixed by the DAG / block lattice).
Let's say there is no DAG, and hence no history which can be used to verify all the transactions up to the genesis block.
Alice has an account worth 1 trillion USD. Bob doesn't like it and decides to pressure (enough of) the representatives to remove Alice's account from their ledgers. Now Alice's money is gone. Everyone else still has Alice's correct account balance, and they don't agree with the change made by the representatives, but they have no voting weight, hence their correctness is practically irrelevant.
Now let's bring back the DAG and the history. If Alice's account balance would be incorrect, she could make a claim that the representatives have colluded to manipulate the ledger. The manipulation can be proven because the history can prove Alice's claim up to the genesis block. The representatives can't prove their claim because they have no DAG proof of their own; they can't fake the DAG without Alice's private key, and without the private keys of anyone who has ever sent nano to Alice, and without the private keys of anyone who has ever received nano from Alice.
Obviously, this is a bit of an idealized scenario because Bob could simply pressure the representatives to block their voting for any spend from Alice's account. However, the money is still there, but can't be spent for the moment.
The protection added by DAG is practically useful for cases where the representatives might be pressured into reverting a single transaction of a user. Without DAG, the representatives could do it freely. With DAG, the more time passes, the more transactions are made into the network, the more difficult it is to make the change without creating total chaos, because all the transactions linked by the DAG to Alice's account must be reverted as well.
But DAG only works if it can be proven up to the genesis block, hence the history is critical.
MOST CONCERNING ATTACK VECTOR
Q: What is the most concerning attack vector?
A: The most concerning attack, regarding to the possibility of tricking people and systems into providing services without payment, is described in the "NETWORK TRAFFIC FILTER ATTACK". This is because this attack requires the attacker to target a single victim node.
Highjacking a node's network traffic isn't easy, but it's far more plausible than highjacking it for the intended victim and for all the representatives (that's needed for the "TWO QUORUMS ATTACK").
If a node were to use an absolute supermajority (65%) as the confirmation quorum, this type of attack becomes absurdly expensive both in the necessary voting weight (30%) and in the necessary resources required to highjacking and filter the network traffic of many geographically distributed nodes.
TAKING REPRESENTATIVES OFFLINE
Q: Could an attacker amass a voting power above the default minimum quorum (22.5% of the total voting power), DDOS the other representatives to bring them offline, and launch a double spend attack with minimal resources?
A: This kind of attack is very hard because some nodes need to protect themselves more than the average nodes, since they deal with a lot more money. They do this by raising the minimum quorum, in the configuration of their nodes.
This means that the required voting power that the attacker needs might have to be 3 times the default minimum quorum, for the attack to produce a significant monetary loss.
Any node could monitor the online voting power and double spend attempts, and could raise the alarm if an attack appears to be happening. At that point, most representatives could increase their minimum quorum.
Q: What happens if all the audit nodes are destroyed and only pruned nodes remain?
A: If the history of blocks vanishes overnight, the network would continue to work normally.
However, a node which is out of sync would hang indefinitely because it would be unable to get the blocks in between the newest block it has and the newest block received from an account. This happens because all blocks are chained and must be processed in the order in which they were chained. To fix this, such nodes have to bootstrap again.
Q: What happens if someone sends nano to an address for which no account exists?
A: The transaction succeeds and the sent nano remains unpocketed until a wallet creates the open block for the receiving account, and then creates the receiving block. The receiving account can be added to a wallet at any time. If the receiving account is never added to a wallet, the sent nano remains unpocketed forever.
Q: What would happen if an attacker were to generate a block with a "Previous" field which is random. What would other nodes do when receiving such a block? Since they can never receive a block with that hash, would they wait forever for it?
A: There is a timeout for waiting for the blocks in between.
See "Block gap synchronization" from https://github.com/nanocurrency/raiblocks/wiki/Attacks
Q: Why does a block contain the hash of the previous block, rather than a pair of account ID - unique integer counter?
A: There is no practical attack scenario which would produce different security results when using a hash or a counter, so long as a receive block would contain the sender's account ID and the receiver's counter, balance and signature.
However, even without a visible attack scenario, avoiding to use a hash is a malleability, which is normally undesirable. See https://en.wikipedia.org/wiki/Malleability_(cryptography)
Aside from this, a counter must be stored in each account, and the account must ensure that what is stored locally is synchronized with what the network knows.
Hash performance should be in the millions per second, so performance by using a hash should be far greater than having to store a counter for each block. Saving a counter would require accessing a separate database page, and this may take milliseconds.
Block chaining and traversal are also simpler because a hash doesn't require a separate saving, like a counter needs, saving which has its own risks.
DISCARDING DOUBLE SPEND BLOCKS
Q: Why aren't all the blocks linked to a double spend discarded? Why is one kept?
A: Let's say that an attacker wants to get a service from a victim, but doesn't want to pay for it. The attacker makes the payment, as required by the victim. The victim provides the service. The attacker double spends in order to invalidate the original payment.
If one block of the double spend is kept, it's most likely that the block with the original payment would be kept because it had time to propagate through the network. This means that the victim gets paid.
If all the blocks linked to a double spend would be discarded, the attacker could double spend a bit later and force the block with the original payment to be discarded as well. This means that the victim would not get paid.
The disadvantage of keeping one block and having to vote to solve the double spend could be that the network is more exposed to DDOS attacks where an attacker could force the network to send around a lot of messages with votes (especially if vote switching is involved).
Q: How would consensus work if only 1 nano remains accessible (or others are lost)?
A: It's not possible to know if an account is accessible or not, but it may be possible to force account owners to periodically perform an account operation that proves accessibility.
It's theoretically possible to include in the protocol some sort of expiration conditions for the delegation of the voting weight of an account toward a representative.
Every account would then have to periodically update its representative (could remain the same, but a new signed block must be added to the account's blockchain).
If an account were to not perform this operation would have its voting weight not counted toward its representative's voting weight. Since the total voting weight of the representatives would slowly decline over time, due to lost coins, the minimum required (absolute) voting weight for the quorum must also be decreased (in the protocol).
In order to avoid attacks by people who would purposefully avoid updating their representative so as to force a reduction of the minimum required (absolute) voting weight for the quorum, the way this minimum is calculated must be changed.
Q: Wouldn't it be better if the voting weight was calculated based on the amount of coins staked by wallets?
A: In such a case, an undetermined number of coins would be available for voting because most accounts would not be online for most of the time.
Using representatives allows the network to use almost all possible votes in a deterministic manner, which in turn allows the confirmation quorum to be relative to the maximum voting weight (133 millions), not to the voting weight of the representatives which are online, which in turn means that knocking representatives offline can't affect the security of the confirmation process.
Also, there is the matter of node security. Voting nodes must be online, so the stakes would also be available online (since there is only one private key for voting, receiving and sending). This exposes very large amounts of money to very high risks, which in turn would make a lot of people avoid staking. This problem can be avoided by having a separate private key for sending, like described in "SEPARATE KEYS FOR SEND AND RECEIVE (FOR OFFLINE SENDS)".
The representative accounts can have even 0 nano.
POTENTIALLY INTERESTING FEATURES FOR THE FUTURE
SEPARATE KEYS FOR SEND AND RECEIVE (FOR OFFLINE SENDS)
PURPOSE: This would make possible maximum security through partially offline accounts, offline sends, and help with pruning of (what are now) permanently pending blocks.
Currently, sends from an offline account are impractical because all of its incoming blocks are pending, so the balance is 0 and therefore nothing can be spent from it. Even though receives can be created offline (and imported in an online node for processing), this way of working is a nightmare for a company which receives a lot of blocks, in terms of time spent doing it, and of trust that has to be put in the employees who do this.
An account should have two private keys: the current key to sign receives and votes, another key to sign sends. The keys must not be replaceable.
This allows a representative to be online in order to vote, but not risk its balance (since the private key for sends is on an offline computer).
This allows accounts to process pending blocks without risking their balance, which means that ledger pruning would not be affected by (what are now) permanently pending blocks. A limit for the number of pending blocks should still exist.
See watch-only accounts: https://github.com/nanocurrency/raiblocks/pull/581
FLOW FOR OFFLINE SENDS
To generate an offline send, a user which has a lot of receives (like an exchange) must: suspend the processing of receives, get the required information to sign, move this information to an offline computer, sign the information, move the signed information back to the online computer, process the send, resume the processing of receives.
Receives must be suspended for offline sends to work. This is because a send requires a reference to the previous block which is processed by the sender, which can be a send or a receive. If the exchange were to keep processing receives, its last processed block would change between the moment when the offline send is initiated and the moment when the signed send would be back online for processing.
CUSTOM DATA FOR BLOCKS
PURPOSE: This would allow users to include their own data in blocks, and also allow off-chain smart contracts.
Add an optional custom data field to the blocks.
This field could be up to 64 bytes and may store, for example, the hash of some off-chain data (like a contract).
If the custom data field is present, the proof of work could be required to be larger.
A 2 bits field containing the size of the custom data could be added to allow for optimizations: 0 = no extra data, 1 = 16 bytes extra data, 2 = 32 bytes extra data, 3 = 64 bytes extra data.
PROBLEM: Having custom data in a block might become a problem if the block is sent to an account whose balance is below the threshold when an account (and its frontier block) is removed from the ledger, during pruning.
DECENTRALIZED VOTING WEIGHTS ACQUISITION
PURPOSE: This is a mechanism which minimizes the influence of a central point of failure in the acquisition of the voting weights of the representatives. Currently, the voting weights of the representatives are hardcoded in the wallet.
This mechanism makes a decentralized delegated-trust system work, in the absence of Proof-of-Work, at least to the extent that the users have to trust the voting weights from the wallets only the first time they use it. Since the users have to trust the wallet every time they update it, it's perfectly fine to trust once the list of voting weights from the wallet.
This mechanism allows a node to obtain information about representatives, like voting weight (and uptime), through the existing dPoS consensus, rather than through cryptographic proofs that are verifiable up to the genesis block.
This mechanism is particularly important for light nodes, nodes which need to be able to bootstrap very quickly. In order to extract the voting weights of the representatives, a light node doesn't need to download the entire ledger, and doesn't need to download the frontiers of all the accounts, it only needs the frontiers of the accounts that it uses (mainly, its own) and the voting weights of the representatives (whose voting weights are used for transaction confirmations).
SUMMARY: Periodically, the top 100 representatives (by voting weight) create snapshots of the voting weight distribution of the top 100 nodes (by voting weight), and broadcast the snapshots. A snapshot is very small, so it can be downloaded in real time. Any light node from the network can "replay" these snapshots starting from the last time it replayed snapshots, so that it ultimately ends up being able to cryptographically verify the voting weight distribution that's agreed by the supermajority of the network. Most of the time, "replaying" just the last snapshot would work, which means that light nodes can get up to speed in real time.
A representative's voting weight is used for transaction confirmations if it's at least 0.1% from the maximum voting weight (133 millions). Currently, there are 43 such representatives.
Let's choose a value MVW = 0.03%, as a percentage from the maximum voting weight (133 millions), so that the number of representatives whose voting weight is at least MVW is much higher than 43. Currently, there are about 100 such representatives; this number is called N.
Every representative whose voting weight was at least MVW in the past week, has to create a snapshot of the voting weights of the representatives (from its ledger) whose voting weight was at least MVW in the past week. More information, like observed uptime, can be added to the snapshot. The snapshot is created once a day, signed and broadcast.
Rebroadcasts have to be done only for the snapshots created by the representatives whose voting weight was at least MVW in the past week, in order to minimize the potential network spamming attacks from malicious representatives.
Because N is small, a snapshot is also small. To identify a representative, 32 bytes are required. The voting weight requires 8 bytes, but this could be reduced to 4 because approximations are fine. The size of a snapshot is about (32 + 8) * 100 = 4 KB.
Each node accumulates these snapshots, one from each representative, into a single snapshot blob. The size of a snapshot blob is about 4 KB * 100 = 400 KB.
A node can request a snapshot blob from any of its peers. Since the blob contains the signatures of the creators of each snapshot, it's fine to request the blob from a single peer.
A node has to cache the last valid snapshot blob. When a node has no cached snapshot blob, the voting weight distribution which is harcoded into the wallet is used instead.
A snapshot has to be validated:
- It must be signed by a representative which is known to the node either from the hardcoded wallet data or from the cached snapshot blobs received in the past week.
- The voting weight of the signer must have been at least MVW either in the hardcoded wallet data or in the cached snapshot blobs received in the past week.
- The signer must be a representative contained in the snapshot.
- The sum of the voting weights of the contained representatives must be below the maximum (133 millions).
The snapshot blob has to be validated:
- The sum of the voting weights of the signers of all the snapshots from the blob, should be at least the supermajority (65%) from the maximum voting weight (133 millions).
Since the snapshots from the snapshot blob will never be identical, in order to handle the differences, a node must create the voting weight distribution as an average voting weight for each representative from the snapshot blob.
The average should be weighted by the voting weight of each signer of a snapshot. The average should be median in order to avoid the effect of dramatic differences in just a few of the snapshots from the same blob, for the same representative. Median average means that the average of [1, 2, 1000] is 2.
A node may add the new / unknown representatives from a snapshot blob if each such representative is voted, in the blob, with an absolute supermajority (65% from the maximum voting weight of 133 millions). The number of votes received by a new representative, in the blob, is equal with the sum of the voting weights of the known representatives which have signed the snapshots in which the new representative is present.
If a node is offline for too long and the voting weight distribution that the node knows (either from the last cached data or from the hardcoded data) doesn't allow it to achieve the required supermajority for the validation of a snapshot blob, because in the meantime there may have been massive changes in the voting weight distribution, the node has to update the voting weight distribution from a trusted party, namely from the developers of the used wallet.
Is this issue important? For most of the network it isn't because the representatives are online most of the time, so they aren't offline long enough for the voting weight distribution to change dramatically, change which could cause the representatives to become unable to validate new snapshot blobs.
This issue can be avoided if the representatives keep a history of the snapshot blobs, and if a node can ask the snapshot blobs starting from a particular date (when they last processed the snapshot blobs). This allows a node to go through all the consecutive snapshot blobs starting from the last known snapshot blob, changing its known voting weight distribution little by little.
Q: What would happen if the voting weight distribution were to change dramatically between consecutive snapshot blobs?
A: Let's say, for example, that all the nodes from the network know that there are only two representatives: A with 90% of the voting weight, and B with 10% of the voting weight.
Let's say that the entire voting weight of A is instantly moved from A to C. Now we have: A with 0% of the voting weight, B with 10% of the voting weight, C with 90% of the voting weight.
All three representatives create snapshots and broadcast them. Because the network doesn't know that C has a voting weight above MVW = 0.03%, it doesn't broadcast its snapshot. However, even though A now has 0% voting weight, the network knows that it had 90% in the past week, so it broadcasts its snapshot.
Now, any node from the network has snapshots from A and B, and their known combined voting weight allows any node to achieve the required supermajority for the validation of a snapshot, so their snapshots are accepted. Therefore, the network updates properly, and A gets 0% voting weight and C gets 90% voting weight.
FAKING LEDGER FOR BOOTSTRAPPING
Q: What would happen if a malicious node creates a fake ledger in which he controls the confirmation quorum, and sends this to others for bootstrapping?
A: The fake ledger would not be validated by the voting weights from the wallet. Therefore, this attack can work only if the attacker can feed the node a malicious wallet, but at that moment all is lost anyway.
But let's ignore this validation. In order to be able to create a fake ledger starting from the genesis block, an attacker would have to be able to send from the genesis account (which is hardcoded in the wallet), which means that the attacker would have to be able to sign the send blocks of the genesis account.
Since only the developers have the private key of the genesis account, only they can create a fake ledger. If the developers wanted to make money, there are much simpler ways to do it, ways that are not (as clearly) theft.
But let's say that an attacker obtains the private key of the genesis account.
Because the attacker needs to control some representative accounts in order to control the confirmation quorum, he must send payments directly from the genesis account to the fake representative accounts.
If the attacker were to not do this now and would first copy all the blocks from the real ledger into the fake ledger, he would later be unable to send payments to the fake representative accounts because he would not be able to sign the send blocks from the copied accounts (since he doesn't have the private keys of the accounts copied from the real ledger).
Because the attacker must send payments directly from the genesis account to the fake representative accounts, all the block hashes of the entire ledger change (compared to the hashes from the real ledger). Because the hashes change, the attacker can't simply copy the open block of the victim, from the real ledger, because the previous block hash contained by the copied open block would not be found in the fake ledger.
This means that the attacker can't later copy any block from the real ledger since their previous block hashes would not match to those from the fake ledger. This means that the fake ledger is entirely fake, and can't contain any block or account from the real ledger.
Because the attacker can't simply copy the open block of the victim, he would have to sign it.
If the attacker has the private key (for signing) of the victim, he doesn't need to create the fake ledger since he would just make a payment in the real ledger.
If the attacker can't sign the open block of the victim, the victim would be unable to validate the fake ledger's stream because his own open block, with his own signature, would have to be in the fake ledger, somewhere.
This means that the attack can succeed only if the victim opens a new account directly in the fake ledger. What's the worst that can happen, considering that the victim's account is empty? The attacker could send a payment from an account he controls (this doesn't affect the real ledger, so the attacker keeps his money), the victim receives it and provides a service in exchange.
Q: But what if the attacker would create a fake ledger by reverting the real ledger to a past state?
A: Creating a fake ledger by reverting a copy of the real ledger to a past state doesn't require the attacker to control the genesis account in order to succeed.
However, the attacker would be able to control enough voting weight to cover the confirmation quorum only if he had already controlled it at the moment from the past where the ledger was reverted. If the confirmation quorum were an absolute supermajority (65%), then the attacker must have controlled in the past the supermajority of the voting weight. This is a gameover scenario for any cryptocurrency because a single entity controls the entire confirmation quorum (or double spend resolution quorum).
This means that this attack would be even more expensive than acquiring a voting weight over 30% from the maximum voting weight (133 millions) while trying to execute a "TWO QUORUMS ATTACK" in the real ledger. Why? Because the current real representatives would not vote in the fake ledger since they have different account frontiers.
In any case, this attack can be performed by very, very few entities, which means the attacker can be tracked down.
PURPOSE: This would increase the network performance linearly with the number of shards.
Sharding means splitting the network in several logical parts such that the overall performance of the sharded network is significantly greater than the performance of the non-sharded network. Consensus requirements remain the same for each shard.
In the configuration of the wallet software, a shard (index) is set for the representative which runs the node and signs the blocks from the network, but only for the configured shard (not for all the shards).
The shard index can be only one of those recognized by the wallet software. This is a problem because it doesn't allow real-time adaptation to network conditions.
The same representative can run in nodes with different shards, preferably on different computers distributed through the world. This way, the same public key and voting weight can be used for any and all shards. It's not mandatory (yet highly desirable) for a representative to run in a node for each of the possible shards.
For an account, a shard can be computed from the account address.
Each block created by an account is processed only by the representative nodes who run for the shards of the sender and of the receiver. This means that there are 2 UDP frames broadcast by the sender.
The network traffic of a block is limited to the shards of the sender and of the receiver, not to the entire network. For example, if there are 100 shards, a block is broadcast to only 2 shards, so 2% of the network.
The consensus in a shard doesn't depend on the consensus in other shards. The voting weight isn't split. The voting weight is duplicated and is separate for each shard, that is, the same representatives operate in every shard, so their signatures can be trusted to the same extent in all shards. Each shard gets its own consensus based on all the representatives who choose to vote in that shard (, having the same voting weight in each shard).
When a send is made, the send block is broadcast to the shards of the sender and of the receiver. If the sender double spends in another shard, the double spend would be detected in the sender's shard by various nodes, nodes which would then broadcast a double spend notification to the shard of the receiver of each block linked to the double spend.
The maximum voting weight in each shard, relative to which the confirmation quorum percentage is determined, should be the maximum voting weight that was ever online in that shard. If the maximum voting weight were the maximum possible (133 millions) for every shard then transactions could end up stalling in the shards with not enough representatives to cover the confirmation quorum.
Shards don't have to be in sync, and no locks are necessary at shard level.
Sharding doesn't affect ledger pruning.
Sharding has the beneficial side effect of increasing the fault tolerance of the entire network because if a representative is knocked offline, only a single shard is affected.
Sharding can, on average, improve performance [number of shards] / 2 times.
REMAINING QUESTIONS FOR DEVELOPERS
Q: How many bits does the address checksum contain?
A: 40 bits.
Q: Can you publish a report on what's happening with the bounties, like a total sum awarded and the number of bugs in the each category?
PENDING BLOCKS AND PRUNING
In order to be able to use offline accounts, for maximum security, an account has to be created on an offline computer and then nano has to be sent to that account.
Q: Is it safe for this nano to remain pending for any timeframe?
Q: Is there a limit for the number of pending blocks for an account?
Q: How are pending blocks handled during pruning?
If pending blocks can't be removed during pruning, pruning would be limited by accounts which are offline a long time (for security reasons).
The section "SEPARATE KEYS FOR SEND AND RECEIVE (FOR OFFLINE SENDS)" offers a solution by making it safe for all accounts to be online to receive.
ISOLATED NETWORK FRAGMENTS
Q: Can nodes transact in a local network, and later come online to publish the blocks?