nanocurrency / nano-node

Nano is digital currency. Its ticker is: XNO and its currency symbol is: Ӿ
https://nano.org
BSD 3-Clause "New" or "Revised" License
3.47k stars 784 forks source link

Improve AEC alignment #4169

Open RickiNano opened 1 year ago

RickiNano commented 1 year ago

Summary

Nodes receives blocks asynchronously, resulting in each node having its own perceptions on when exactly a block was received and thus affecting the associated LRU (Least Recent Use). When a node selects a block for the AEC, it sorts the bucket by LRU and choose the block from the account with the least recent use. This works well under normal circumstances.

However, during a spam attack, the LRU timings become extremely tight and the diverging values from one node to another leads to nodes picking their own set of blocks for the AEC and reducing the chances of consensus. AEC alignment could be reached if blocks were sorted by block hash instead, since these values are the same for all nodes. However, sorting by hash only would remove the prioritization of accounts with low usage

Proposed solution:

  1. Round the LRU value to nearest minute
  2. AEC candidates are still prioritized by LRU first, but then sorted by block hash

Since local LRU values are not precise to begin with, I suggest reducing the precision of the LRU data type to one minute. This will group all blocks into one-minute "segments" that are much more likely to be the same across the network. With many blocks now sharing the same LRU value (or segment), the node should sort these candidates by block hash, as the hash value will always be the same across the network.

This approach can be improved further by sorting the last two LRU segments instead just one. This is because node A may receive a block at 11:26:59 while node B gets the block at 11:27:00 and thus putting it into another segment. By always considering the last two LRU segments we have the required overlap to always have perfect AEC alignment

What problem would be solved by this feature?

Faster consensus Reduced voting traffic Higher CPS

Are there any previous requests for this feature?

This has been discussed multiple times on Discord, reddit and the Nano forum. This is an attempt to make a concrete solution description

Do you have a suggested solution?

Described in the summary

If this feature is approved, would you be willing to submit a pull request with the solution?

I am willing to collaborate

Possible solution

Described in the summary

Supporting files

No response

RickiNano commented 1 year ago

Gr0vity compiled a version of the node that rounds the LRU time to the nearest minute and simulated on a local desynced network image image Discussion can be found here> https://discord.com/channels/370266023905198083/769209197333053511/1082049233886134393

ATXMJ commented 4 months ago

Out of curiosity, why was "nearest minute" chosen for this concept?

Would it not potentially be more optimal to group AEC candidates into N dynamic LRU "buckets" with a range from 0 to max(LRU), and sort by block hash within each LRU bucket?

gr0vity-dev commented 4 months ago

I think it already considers the bucket. It just rounds the timestamp (last account modification time), then sorts by hash and inserts it into the correct bucket. So blocks coming from accounts modified within the same minute are sorted by hash before being added to the priority queue. AEC then pulls blocks from the priority queue in a round robin manner iterating through the different buckets.

Nodes across the network may have slightly different timestamps for when an account was last modified. This means that different blocks would be activated by different nodes. The idea was that if you round to 1 minute and then sort by hash, the election activation for a hash would be more in line across nodes.

However with the latest improvements, this change no longer brings any performance improvement. I just did a test using a local network here :

Screenshot 2024-02-24 at 14 28 19
ATXMJ commented 4 months ago

I didn't mean the balance buckets.

I meant a new LRU-time-based segmentation of the candidate blocks.

Something like N blocks evenly segmented from time 0 to time max(LRU), rather than segmentation by minute.