Skip to content

Commit 1d83141

Browse files
committed
Merge branch 'loaderror' of git://github.com/sipa/bitcoin
2 parents efb6d9a + 3987741 commit 1d83141

File tree

8 files changed

+90
-26
lines changed

8 files changed

+90
-26
lines changed

src/init.cpp

Lines changed: 61 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ void Shutdown(void* parg)
8282
if (fFirstThread)
8383
{
8484
fShutdown = true;
85+
fRequestShutdown = true;
8586
nTransactionsUpdated++;
8687
bitdb.Flush(false);
8788
{
@@ -791,27 +792,69 @@ bool AppInit2()
791792
nTotalCache -= nCoinDBCache;
792793
nCoinCacheSize = nTotalCache / 300; // coins in memory require around 300 bytes
793794

794-
uiInterface.InitMessage(_("Loading block index..."));
795+
bool fLoaded = false;
796+
while (!fLoaded) {
797+
bool fReset = fReindex;
798+
std::string strLoadError;
795799

796-
nStart = GetTimeMillis();
797-
pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex);
798-
pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex);
799-
pcoinsTip = new CCoinsViewCache(*pcoinsdbview);
800-
801-
if (fReindex)
802-
pblocktree->WriteReindexing(true);
803-
804-
if (!LoadBlockIndex())
805-
return InitError(_("Error loading block database"));
800+
uiInterface.InitMessage(_("Loading block index..."));
806801

807-
// Initialize the block index (no-op if non-empty database was already loaded)
808-
if (!InitBlockIndex())
809-
return InitError(_("Error initializing block database"));
810-
811-
uiInterface.InitMessage(_("Verifying block database integrity..."));
802+
nStart = GetTimeMillis();
803+
do {
804+
try {
805+
UnloadBlockIndex();
806+
delete pcoinsTip;
807+
delete pcoinsdbview;
808+
delete pblocktree;
809+
810+
pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex);
811+
pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex);
812+
pcoinsTip = new CCoinsViewCache(*pcoinsdbview);
813+
814+
if (fReindex)
815+
pblocktree->WriteReindexing(true);
816+
817+
if (!LoadBlockIndex()) {
818+
strLoadError = _("Error loading block database");
819+
break;
820+
}
821+
822+
// Initialize the block index (no-op if non-empty database was already loaded)
823+
if (!InitBlockIndex()) {
824+
strLoadError = _("Error initializing block database");
825+
break;
826+
}
827+
828+
uiInterface.InitMessage(_("Verifying block database integrity..."));
829+
if (!VerifyDB()) {
830+
strLoadError = _("Corrupted block database detected");
831+
break;
832+
}
833+
} catch(std::exception &e) {
834+
strLoadError = _("Error opening block database");
835+
break;
836+
}
812837

813-
if (!VerifyDB())
814-
return InitError(_("Corrupted block database detected. Please restart the client with -reindex."));
838+
fLoaded = true;
839+
} while(false);
840+
841+
if (!fLoaded) {
842+
// first suggest a reindex
843+
if (!fReset) {
844+
bool fRet = uiInterface.ThreadSafeMessageBox(
845+
strLoadError + ".\n" + _("Do you want to rebuild the block database now?"),
846+
"", CClientUIInterface::MSG_ERROR | CClientUIInterface::BTN_ABORT);
847+
if (fRet) {
848+
fReindex = true;
849+
fRequestShutdown = false;
850+
} else {
851+
return false;
852+
}
853+
} else {
854+
return InitError(strLoadError);
855+
}
856+
}
857+
}
815858

816859
if (mapArgs.count("-txindex") && fTxIndex != GetBoolArg("-txindex", false))
817860
return InitError(_("You need to rebuild the databases using -reindex to change -txindex"));

src/main.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2653,6 +2653,18 @@ bool VerifyDB() {
26532653
return true;
26542654
}
26552655

2656+
void UnloadBlockIndex()
2657+
{
2658+
mapBlockIndex.clear();
2659+
setBlockIndexValid.clear();
2660+
pindexGenesisBlock = NULL;
2661+
nBestHeight = 0;
2662+
bnBestChainWork = 0;
2663+
bnBestInvalidWork = 0;
2664+
hashBestChain = 0;
2665+
pindexBest = NULL;
2666+
}
2667+
26562668
bool LoadBlockIndex()
26572669
{
26582670
if (fTestNet)

src/main.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp = NULL);
139139
bool InitBlockIndex();
140140
/** Load the block tree and coins database from disk */
141141
bool LoadBlockIndex();
142+
/** Unload database information */
143+
void UnloadBlockIndex();
142144
/** Verify consistency of the block and coin databases */
143145
bool VerifyDB();
144146
/** Print the loaded block tree */

src/noui.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
#include <string>
1111

12-
static int noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style)
12+
static bool noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style)
1313
{
1414
std::string strCaption;
1515
// Check for usage of predefined caption
@@ -29,7 +29,7 @@ static int noui_ThreadSafeMessageBox(const std::string& message, const std::stri
2929

3030
printf("%s: %s\n", strCaption.c_str(), message.c_str());
3131
fprintf(stderr, "%s: %s\n", strCaption.c_str(), message.c_str());
32-
return 4;
32+
return false;
3333
}
3434

3535
static bool noui_ThreadSafeAskFee(int64 /*nFeeRequired*/)

src/qt/bitcoin.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,23 +34,27 @@ Q_IMPORT_PLUGIN(qtaccessiblewidgets)
3434
static BitcoinGUI *guiref;
3535
static QSplashScreen *splashref;
3636

37-
static void ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style)
37+
static bool ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style)
3838
{
3939
// Message from network thread
4040
if(guiref)
4141
{
4242
bool modal = (style & CClientUIInterface::MODAL);
43+
bool ret = false;
4344
// In case of modal message, use blocking connection to wait for user to click a button
4445
QMetaObject::invokeMethod(guiref, "message",
4546
modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection,
4647
Q_ARG(QString, QString::fromStdString(caption)),
4748
Q_ARG(QString, QString::fromStdString(message)),
48-
Q_ARG(unsigned int, style));
49+
Q_ARG(unsigned int, style),
50+
Q_ARG(bool*, &ret));
51+
return ret;
4952
}
5053
else
5154
{
5255
printf("%s: %s\n", caption.c_str(), message.c_str());
5356
fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str());
57+
return false;
5458
}
5559
}
5660

src/qt/bitcoingui.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,7 @@ void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks)
606606
progressBar->setToolTip(tooltip);
607607
}
608608

609-
void BitcoinGUI::message(const QString &title, const QString &message, unsigned int style)
609+
void BitcoinGUI::message(const QString &title, const QString &message, unsigned int style, bool *ret)
610610
{
611611
QString strTitle = tr("Bitcoin") + " - ";
612612
// Default to information icon
@@ -646,7 +646,9 @@ void BitcoinGUI::message(const QString &title, const QString &message, unsigned
646646
buttons = QMessageBox::Ok;
647647

648648
QMessageBox mBox((QMessageBox::Icon)nMBoxIcon, strTitle, message, buttons);
649-
mBox.exec();
649+
int r = mBox.exec();
650+
if (ret != NULL)
651+
*ret = r == QMessageBox::Ok;
650652
}
651653
else
652654
notificator->notify((Notificator::Class)nNotifyIcon, strTitle, message);

src/qt/bitcoingui.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,9 @@ public slots:
126126
@param[in] message the displayed text
127127
@param[in] style modality and style definitions (icon and used buttons - buttons only for message boxes)
128128
@see CClientUIInterface::MessageBoxFlags
129+
@param[in] ret pointer to a bool that will be modified to whether Ok was clicked (modal only)
129130
*/
130-
void message(const QString &title, const QString &message, unsigned int style);
131+
void message(const QString &title, const QString &message, unsigned int style, bool *ret = NULL);
131132
/** Asks the user whether to pay the transaction fee or to cancel the transaction.
132133
It is currently not possible to pass a return value to another thread through
133134
BlockingQueuedConnection, so an indirected pointer is used.

src/ui_interface.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class CClientUIInterface
6868
};
6969

7070
/** Show message box. */
71-
boost::signals2::signal<void (const std::string& message, const std::string& caption, unsigned int style)> ThreadSafeMessageBox;
71+
boost::signals2::signal<bool (const std::string& message, const std::string& caption, unsigned int style), boost::signals2::last_value<bool> > ThreadSafeMessageBox;
7272

7373
/** Ask the user whether they want to pay a fee or not. */
7474
boost::signals2::signal<bool (int64 nFeeRequired), boost::signals2::last_value<bool> > ThreadSafeAskFee;

0 commit comments

Comments
 (0)