Improve block database load error reporting
This commit is contained in:
parent
2f0fa79db2
commit
398774181a
8 changed files with 87 additions and 23 deletions
55
src/init.cpp
55
src/init.cpp
|
@ -82,6 +82,7 @@ void Shutdown(void* parg)
|
|||
if (fFirstThread)
|
||||
{
|
||||
fShutdown = true;
|
||||
fRequestShutdown = true;
|
||||
nTransactionsUpdated++;
|
||||
bitdb.Flush(false);
|
||||
{
|
||||
|
@ -791,9 +792,21 @@ bool AppInit2()
|
|||
nTotalCache -= nCoinDBCache;
|
||||
nCoinCacheSize = nTotalCache / 300; // coins in memory require around 300 bytes
|
||||
|
||||
bool fLoaded = false;
|
||||
while (!fLoaded) {
|
||||
bool fReset = fReindex;
|
||||
std::string strLoadError;
|
||||
|
||||
uiInterface.InitMessage(_("Loading block index..."));
|
||||
|
||||
nStart = GetTimeMillis();
|
||||
do {
|
||||
try {
|
||||
UnloadBlockIndex();
|
||||
delete pcoinsTip;
|
||||
delete pcoinsdbview;
|
||||
delete pblocktree;
|
||||
|
||||
pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex);
|
||||
pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex);
|
||||
pcoinsTip = new CCoinsViewCache(*pcoinsdbview);
|
||||
|
@ -801,17 +814,47 @@ bool AppInit2()
|
|||
if (fReindex)
|
||||
pblocktree->WriteReindexing(true);
|
||||
|
||||
if (!LoadBlockIndex())
|
||||
return InitError(_("Error loading block database"));
|
||||
if (!LoadBlockIndex()) {
|
||||
strLoadError = _("Error loading block database");
|
||||
break;
|
||||
}
|
||||
|
||||
// Initialize the block index (no-op if non-empty database was already loaded)
|
||||
if (!InitBlockIndex())
|
||||
return InitError(_("Error initializing block database"));
|
||||
if (!InitBlockIndex()) {
|
||||
strLoadError = _("Error initializing block database");
|
||||
break;
|
||||
}
|
||||
|
||||
uiInterface.InitMessage(_("Verifying block database integrity..."));
|
||||
if (!VerifyDB()) {
|
||||
strLoadError = _("Corrupted block database detected");
|
||||
break;
|
||||
}
|
||||
} catch(std::exception &e) {
|
||||
strLoadError = _("Error opening block database");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!VerifyDB())
|
||||
return InitError(_("Corrupted block database detected. Please restart the client with -reindex."));
|
||||
fLoaded = true;
|
||||
} while(false);
|
||||
|
||||
if (!fLoaded) {
|
||||
// first suggest a reindex
|
||||
if (!fReset) {
|
||||
bool fRet = uiInterface.ThreadSafeMessageBox(
|
||||
strLoadError + ".\n" + _("Do you want to rebuild the block database now?"),
|
||||
"", CClientUIInterface::MSG_ERROR | CClientUIInterface::BTN_ABORT);
|
||||
if (fRet) {
|
||||
fReindex = true;
|
||||
fRequestShutdown = false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return InitError(strLoadError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mapArgs.count("-txindex") && fTxIndex != GetBoolArg("-txindex", false))
|
||||
return InitError(_("You need to rebuild the databases using -reindex to change -txindex"));
|
||||
|
|
12
src/main.cpp
12
src/main.cpp
|
@ -2653,6 +2653,18 @@ bool VerifyDB() {
|
|||
return true;
|
||||
}
|
||||
|
||||
void UnloadBlockIndex()
|
||||
{
|
||||
mapBlockIndex.clear();
|
||||
setBlockIndexValid.clear();
|
||||
pindexGenesisBlock = NULL;
|
||||
nBestHeight = 0;
|
||||
bnBestChainWork = 0;
|
||||
bnBestInvalidWork = 0;
|
||||
hashBestChain = 0;
|
||||
pindexBest = NULL;
|
||||
}
|
||||
|
||||
bool LoadBlockIndex()
|
||||
{
|
||||
if (fTestNet)
|
||||
|
|
|
@ -139,6 +139,8 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp = NULL);
|
|||
bool InitBlockIndex();
|
||||
/** Load the block tree and coins database from disk */
|
||||
bool LoadBlockIndex();
|
||||
/** Unload database information */
|
||||
void UnloadBlockIndex();
|
||||
/** Verify consistency of the block and coin databases */
|
||||
bool VerifyDB();
|
||||
/** Print the loaded block tree */
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
static int noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style)
|
||||
static bool noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style)
|
||||
{
|
||||
std::string strCaption;
|
||||
// Check for usage of predefined caption
|
||||
|
@ -29,7 +29,7 @@ static int noui_ThreadSafeMessageBox(const std::string& message, const std::stri
|
|||
|
||||
printf("%s: %s\n", strCaption.c_str(), message.c_str());
|
||||
fprintf(stderr, "%s: %s\n", strCaption.c_str(), message.c_str());
|
||||
return 4;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool noui_ThreadSafeAskFee(int64 /*nFeeRequired*/)
|
||||
|
|
|
@ -34,23 +34,27 @@ Q_IMPORT_PLUGIN(qtaccessiblewidgets)
|
|||
static BitcoinGUI *guiref;
|
||||
static QSplashScreen *splashref;
|
||||
|
||||
static void ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style)
|
||||
static bool ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style)
|
||||
{
|
||||
// Message from network thread
|
||||
if(guiref)
|
||||
{
|
||||
bool modal = (style & CClientUIInterface::MODAL);
|
||||
bool ret = false;
|
||||
// In case of modal message, use blocking connection to wait for user to click a button
|
||||
QMetaObject::invokeMethod(guiref, "message",
|
||||
modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection,
|
||||
Q_ARG(QString, QString::fromStdString(caption)),
|
||||
Q_ARG(QString, QString::fromStdString(message)),
|
||||
Q_ARG(unsigned int, style));
|
||||
Q_ARG(unsigned int, style),
|
||||
Q_ARG(bool*, &ret));
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s: %s\n", caption.c_str(), message.c_str());
|
||||
fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -606,7 +606,7 @@ void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks)
|
|||
progressBar->setToolTip(tooltip);
|
||||
}
|
||||
|
||||
void BitcoinGUI::message(const QString &title, const QString &message, unsigned int style)
|
||||
void BitcoinGUI::message(const QString &title, const QString &message, unsigned int style, bool *ret)
|
||||
{
|
||||
QString strTitle = tr("Bitcoin") + " - ";
|
||||
// Default to information icon
|
||||
|
@ -646,7 +646,9 @@ void BitcoinGUI::message(const QString &title, const QString &message, unsigned
|
|||
buttons = QMessageBox::Ok;
|
||||
|
||||
QMessageBox mBox((QMessageBox::Icon)nMBoxIcon, strTitle, message, buttons);
|
||||
mBox.exec();
|
||||
int r = mBox.exec();
|
||||
if (ret != NULL)
|
||||
*ret = r == QMessageBox::Ok;
|
||||
}
|
||||
else
|
||||
notificator->notify((Notificator::Class)nNotifyIcon, strTitle, message);
|
||||
|
|
|
@ -126,8 +126,9 @@ public slots:
|
|||
@param[in] message the displayed text
|
||||
@param[in] style modality and style definitions (icon and used buttons - buttons only for message boxes)
|
||||
@see CClientUIInterface::MessageBoxFlags
|
||||
@param[in] ret pointer to a bool that will be modified to whether Ok was clicked (modal only)
|
||||
*/
|
||||
void message(const QString &title, const QString &message, unsigned int style);
|
||||
void message(const QString &title, const QString &message, unsigned int style, bool *ret = NULL);
|
||||
/** Asks the user whether to pay the transaction fee or to cancel the transaction.
|
||||
It is currently not possible to pass a return value to another thread through
|
||||
BlockingQueuedConnection, so an indirected pointer is used.
|
||||
|
|
|
@ -68,7 +68,7 @@ public:
|
|||
};
|
||||
|
||||
/** Show message box. */
|
||||
boost::signals2::signal<void (const std::string& message, const std::string& caption, unsigned int style)> ThreadSafeMessageBox;
|
||||
boost::signals2::signal<bool (const std::string& message, const std::string& caption, unsigned int style), boost::signals2::last_value<bool> > ThreadSafeMessageBox;
|
||||
|
||||
/** Ask the user whether they want to pay a fee or not. */
|
||||
boost::signals2::signal<bool (int64 nFeeRequired), boost::signals2::last_value<bool> > ThreadSafeAskFee;
|
||||
|
|
Loading…
Reference in a new issue