X-CASH-official / xcash-core

📦 First Cryptonote coin with public & private transactions, custom DPOS consensus
https://xcash.foundation
Other
66 stars 20 forks source link

[bug] If all seed nodes are down, xcashd gets caught in an infinite loop #23

Closed ghost closed 2 years ago

ghost commented 2 years ago

🐛 BUG REPORT

Expected Behavior The do/while loop in src/cryptonote_core/blockchain.cpp at line 4082 randomly selects seed nodes to try to connect to. If one is already tried, it's tracked and not tried again so that you're guaranteed that all available seed nodes are attempted in a random fashion.

Current Behavior The do/while loop works correctly when cycling the first time through available seed nodes. However, if all seed nodes are down, the tracking array is not cleared when the last one is tried and the loop to pick the next seed node never exits, resulting in an infinite loop which locks the thread and spikes the cpu. Likely the only solution to this is to restart xcashd (at which point if the seed nodes are still down, it'll eventually lock again).

Possible Solution My suggestion would be to reset the tracking array just prior to the do/while.

Something like: if (network_data_nodes_array[NETWORK_DATA_NODES_AMOUNT-1] != 0) { // all seed nodes have been tried, time to reset and try again memset(network_data_nodes_array, 0x00, sizeof(network_data_nodes_array)); }

Steps to Reproduce (for bugs) Bring down all seed nodes :smile:

Context Just running the xcashd daemon. This will happen for either a stand-alone node or a delegate.

Your Environment Just running a local node and noticed that my cpu spiked whenever we had a seed node outage. During this time it makes a nice room warmer, however.

zachhildreth commented 2 years ago

Thanks @CygnusMiner

I tried a POC and it does fix the infinite loop error!

I decided to use std::fill instead of memset just to keep with the C++ style of the codebase.

if (network_data_nodes_array[NETWORK_DATA_NODES_AMOUNT-1] != 0)
{
  std::fill(network_data_nodes_array, network_data_nodes_array+NETWORK_DATA_NODES_AMOUNT, 0);
}

I will add it in once I can test on the network