Browse Source

Improve block database load error reporting

tags/v0.15.1
Pieter Wuille 8 years ago
parent
commit
f7f3a96b74
9 changed files with 94 additions and 26 deletions
  1. 4
    0
      src/checkqueue.h
  2. 61
    18
      src/init.cpp
  3. 12
    0
      src/main.cpp
  4. 2
    0
      src/main.h
  5. 2
    2
      src/noui.cpp
  6. 6
    2
      src/qt/bitcoin.cpp
  7. 4
    2
      src/qt/bitcoingui.cpp
  8. 2
    1
      src/qt/bitcoingui.h
  9. 1
    1
      src/ui_interface.h

+ 4
- 0
src/checkqueue.h View File

@@ -163,6 +163,10 @@ public:
condQuit.wait(lock);
}

~CCheckQueue() {
Quit();
}

friend class CCheckQueueControl<T>;
};


+ 61
- 18
src/init.cpp View File

@@ -82,6 +82,7 @@ void Shutdown(void* parg)
if (fFirstThread)
{
fShutdown = true;
fRequestShutdown = true;
nTransactionsUpdated++;
bitdb.Flush(false);
{
@@ -791,27 +792,69 @@ bool AppInit2()
nTotalCache -= nCoinDBCache;
nCoinCacheSize = nTotalCache / 300; // coins in memory require around 300 bytes

uiInterface.InitMessage(_("Loading block index..."));
bool fLoaded = false;
while (!fLoaded) {
bool fReset = fReindex;
std::string strLoadError;

nStart = GetTimeMillis();
pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex);
pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex);
pcoinsTip = new CCoinsViewCache(*pcoinsdbview);

if (fReindex)
pblocktree->WriteReindexing(true);

if (!LoadBlockIndex())
return InitError(_("Error loading block database"));
uiInterface.InitMessage(_("Loading block index..."));

// Initialize the block index (no-op if non-empty database was already loaded)
if (!InitBlockIndex())
return InitError(_("Error initializing block database"));

uiInterface.InitMessage(_("Verifying block database integrity..."));
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);

if (fReindex)
pblocktree->WriteReindexing(true);

if (!LoadBlockIndex()) {
strLoadError = _("Error loading block database");
break;
}

// Initialize the block index (no-op if non-empty database was already loaded)
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
- 0
src/main.cpp View File

@@ -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)

+ 2
- 0
src/main.h View File

@@ -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 */

+ 2
- 2
src/noui.cpp View File

@@ -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*/)

+ 6
- 2
src/qt/bitcoin.cpp View File

@@ -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;
}
}


+ 4
- 2
src/qt/bitcoingui.cpp View File

@@ -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);

+ 2
- 1
src/qt/bitcoingui.h View File

@@ -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.

+ 1
- 1
src/ui_interface.h View File

@@ -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…
Cancel
Save