Skip to content

Commit

Permalink
fix: attempt to handle assertion error due to ungraceful shutdown on …
Browse files Browse the repository at this point in the history
…client restart

Replace assertion with proper error handling in checkpointsync.cpp to gracefully handle cases where the client doesn't shut down properly. 

This change:

- Handles the assertion that occasionally causes the client to become unresponsive
- Implements a multi-step recovery process to find valid checkpoints
- Adds detailed logging for diagnostic purposes
- Maintains chain consistency by preferring recent valid blocks
- Suggests a reindex as a last resort

This fix prevents the client from crashing when mapBlockIndex doesn't contain the expected checkpoint after an ungraceful shutdown (power loss, hardware failure, etc).
  • Loading branch information
Dhop14 authored Dec 18, 2024
1 parent 44d070a commit f9fe7c6
Showing 1 changed file with 21 additions and 3 deletions.
24 changes: 21 additions & 3 deletions src/checkpointsync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,30 @@ bool CheckSyncCheckpoint(const uint256 hashBlock, const int nHeight, const CBloc
return true;
}
}

const CBlockIndex* pindexSync;
{
LOCK2(cs_main, cs_hashSyncCheckpoint);
// sync-checkpoint should always be accepted block
assert(mapBlockIndex.count(hashSyncCheckpoint));
// sync-checkpoint should be an accepted block
if (!mapBlockIndex.count(hashSyncCheckpoint)) {
LogPrintf("Checkpoints: %s: WARNING - Sync checkpoint %s not found in block index after unclean shutdown\n",
__func__, hashSyncCheckpoint.ToString());
LogPrint(BCLog::NET, "Checkpoints: Attempting recovery of sync checkpoint state\n");

// Attempt to recover by resetting the sync checkpoint
if (!ResetSyncCheckpoint()) {
// If reset fails, we need to inform the user that a reindex might be necessary
LogPrintf("Checkpoints: %s: CRITICAL - Failed to reset sync checkpoint. A reindex may be required.\n", __func__);
return error("%s: Sync checkpoint recovery failed - please restart with -reindex", __func__);
}

// After reset, we should have a valid checkpoint
if (!mapBlockIndex.count(hashSyncCheckpoint)) {
LogPrintf("Checkpoints: %s: CRITICAL - Failed to recover sync checkpoint state after reset attempt\n", __func__);
return error("%s: Failed to recover sync checkpoint state", __func__);
}
LogPrint(BCLog::NET, "Checkpoints: Successfully recovered sync checkpoint state\n");
}
pindexSync = mapBlockIndex[hashSyncCheckpoint];
}

Expand Down

0 comments on commit f9fe7c6

Please sign in to comment.