Catch UTXO set read errors and shutdown

Github-Pull: #5619
Rebased-From: 13cdce4336
This commit is contained in:
Pieter Wuille 2015-01-08 14:38:06 +01:00 committed by Wladimir J. van der Laan
parent a3a73170a9
commit 4e7c219122
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6

View File

@ -112,7 +112,28 @@ bool ShutdownRequested()
return fRequestShutdown; return fRequestShutdown;
} }
class CCoinsViewErrorCatcher : public CCoinsViewBacked
{
public:
CCoinsViewErrorCatcher(CCoinsView* view) : CCoinsViewBacked(view) {}
bool GetCoins(const uint256 &txid, CCoins &coins) const {
try {
return CCoinsViewBacked::GetCoins(txid, coins);
} catch(const std::runtime_error& e) {
uiInterface.ThreadSafeMessageBox(_("Error reading from database, shutting down."), "", CClientUIInterface::MSG_ERROR);
LogPrintf("Error reading from database: %s\n", e.what());
// Starting the shutdown sequence and returning false to the caller would be
// interpreted as 'entry not found' (as opposed to unable to read data), and
// could lead to invalid interpration. Just exit immediately, as we can't
// continue anyway, and all writes should be atomic.
abort();
}
}
// Writes do not need similar protection, as failure to write is handled by the caller.
};
static CCoinsViewDB *pcoinsdbview = NULL; static CCoinsViewDB *pcoinsdbview = NULL;
static CCoinsViewErrorCatcher *pcoinscatcher = NULL;
void Shutdown() void Shutdown()
{ {
@ -155,6 +176,8 @@ void Shutdown()
} }
delete pcoinsTip; delete pcoinsTip;
pcoinsTip = NULL; pcoinsTip = NULL;
delete pcoinscatcher;
pcoinscatcher = NULL;
delete pcoinsdbview; delete pcoinsdbview;
pcoinsdbview = NULL; pcoinsdbview = NULL;
delete pblocktree; delete pblocktree;
@ -986,11 +1009,13 @@ bool AppInit2(boost::thread_group& threadGroup)
UnloadBlockIndex(); UnloadBlockIndex();
delete pcoinsTip; delete pcoinsTip;
delete pcoinsdbview; delete pcoinsdbview;
delete pcoinscatcher;
delete pblocktree; delete pblocktree;
pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex); pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex);
pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex); pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex);
pcoinsTip = new CCoinsViewCache(pcoinsdbview); pcoinscatcher = new CCoinsViewErrorCatcher(pcoinsdbview);
pcoinsTip = new CCoinsViewCache(pcoinscatcher);
if (fReindex) if (fReindex)
pblocktree->WriteReindexing(true); pblocktree->WriteReindexing(true);