Skip to content

Commit

Permalink
Persistence : fix hang when SP watermark cannot be located
Browse files Browse the repository at this point in the history
The methodology for loading persistence relies on walking backwards through persistence files until either a) we run out of persistence files or b) we run out of blocks.

This is done via a while loop, but the while is based on persistedBlocks.size() which is only changed if persistedBlocks.find() is successful in locating the block.  Thus if persistedBlocks.find() is unsuccesful (for example in the case of failed persistence loads) then the while loop will keep iterating - subtracting a block from curTip and trying to load state from persistence files again - over and over all the way back to the genesis block.

This manifests in an apparently hung client.

This commit adds an exit from the while after MAX_STATE_HISTORY+1 load attempts to prevent the issue.
  • Loading branch information
zathras-crypto committed Apr 28, 2015
1 parent 543dcd1 commit 5987063
Showing 1 changed file with 6 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/mastercore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2042,8 +2042,11 @@ static int load_most_relevant_state()
// using the SP's watermark after its fixed-up as the tip
// walk backwards until we find a valid and full set of persisted state files
// for each block we discard, roll back the SP database
// Note: to avoid rolling back all the way to the genesis block (which appears as if client is hung) abort after MAX_STATE_HISTORY attempts
CBlockIndex const *curTip = spBlockIndex;
while (NULL != curTip && persistedBlocks.size() > 0) {
int abortRollBackBlock;
if (curTip != NULL) abortRollBackBlock = curTip->nHeight - MAX_STATE_HISTORY+1;
while (NULL != curTip && persistedBlocks.size() > 0 && curTip->nHeight > abortRollBackBlock) {
if (persistedBlocks.find(spBlockIndex->GetBlockHash()) != persistedBlocks.end()) {
int success = -1;
for (int i = 0; i < NUM_FILETYPES; ++i) {
Expand Down Expand Up @@ -2421,6 +2424,8 @@ int mastercore_init()
if (readPersistence())
{
nWaterlineBlock = load_most_relevant_state();
PrintToConsole("Loading persistent state: %s\n", nWaterlineBlock>0 ?
"OK" : "FAILED (this is normal if this is the first time OmniCore is being run)");
if (nWaterlineBlock < 0) {
// persistence says we reparse!, nuke some stuff in case the partial loads left stale bits
clear_all_state();
Expand Down

0 comments on commit 5987063

Please sign in to comment.