aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@exmulti.com>2012-10-20 13:36:36 -0700
committerJeff Garzik <jgarzik@exmulti.com>2012-10-20 13:36:36 -0700
commit38ac953b9df1f7a884c1ef0e94301e14c4e7477d (patch)
tree03ba74b23e9ccf077fc234e02af068cf40397fd1
parentdee0ee2ac9d6feb49eac9683c01a0eeed4389449 (diff)
parent66b02c93e69cfeaec6e7fa19a03bfb2649025a56 (diff)
downloadbitcoin-38ac953b9df1f7a884c1ef0e94301e14c4e7477d.tar.xz
Merge pull request #1880 from sipa/threadimport
Move external block import to separate thread
-rw-r--r--src/init.cpp22
-rw-r--r--src/main.cpp60
-rw-r--r--src/main.h3
-rw-r--r--src/net.h1
-rw-r--r--src/qt/bitcoingui.cpp4
-rw-r--r--src/qt/clientmodel.cpp5
-rw-r--r--src/qt/clientmodel.h2
7 files changed, 70 insertions, 27 deletions
diff --git a/src/init.cpp b/src/init.cpp
index 8a928218b2..92c752a8f5 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -776,29 +776,13 @@ bool AppInit2()
// ********************************************************* Step 9: import blocks
+ std::vector<boost::filesystem::path> *vPath = new std::vector<boost::filesystem::path>();
if (mapArgs.count("-loadblock"))
{
- uiInterface.InitMessage(_("Importing blockchain data file."));
-
BOOST_FOREACH(string strFile, mapMultiArgs["-loadblock"])
- {
- FILE *file = fopen(strFile.c_str(), "rb");
- if (file)
- LoadExternalBlockFile(file);
- }
- }
-
- filesystem::path pathBootstrap = GetDataDir() / "bootstrap.dat";
- if (filesystem::exists(pathBootstrap)) {
- uiInterface.InitMessage(_("Importing bootstrap blockchain data file."));
-
- FILE *file = fopen(pathBootstrap.string().c_str(), "rb");
- if (file) {
- filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old";
- LoadExternalBlockFile(file);
- RenameOver(pathBootstrap, pathBootstrapOld);
- }
+ vPath->push_back(strFile);
}
+ NewThread(ThreadImport, vPath);
// ********************************************************* Step 10: load peers
diff --git a/src/main.cpp b/src/main.cpp
index fb2e650ac4..43bb4b1793 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -38,6 +38,7 @@ CBigNum bnBestInvalidWork = 0;
uint256 hashBestChain = 0;
CBlockIndex* pindexBest = NULL;
int64 nTimeBestReceived = 0;
+bool fImporting = false;
CMedianFilter<int> cPeerBlockCounts(5, 0); // Amount of blocks that other nodes claim to have
@@ -2251,7 +2252,6 @@ bool LoadExternalBlockFile(FILE* fileIn)
int nLoaded = 0;
{
- LOCK(cs_main);
try {
CAutoFile blkdat(fileIn, SER_DISK, CLIENT_VERSION);
unsigned int nPos = 0;
@@ -2288,6 +2288,7 @@ bool LoadExternalBlockFile(FILE* fileIn)
{
CBlock block;
blkdat >> block;
+ LOCK(cs_main);
if (ProcessBlock(NULL,&block))
{
nLoaded++;
@@ -2305,6 +2306,54 @@ bool LoadExternalBlockFile(FILE* fileIn)
return nLoaded > 0;
}
+struct CImportingNow
+{
+ CImportingNow() {
+ assert(fImporting == false);
+ fImporting = true;
+ }
+
+ ~CImportingNow() {
+ assert(fImporting == true);
+ fImporting = false;
+ }
+};
+
+void ThreadImport(void *data) {
+ std::vector<boost::filesystem::path> *vFiles = reinterpret_cast<std::vector<boost::filesystem::path>*>(data);
+
+ RenameThread("bitcoin-loadblk");
+
+ CImportingNow imp;
+ vnThreadsRunning[THREAD_IMPORT]++;
+
+ // -loadblock=
+ uiInterface.InitMessage(_("Starting block import..."));
+ BOOST_FOREACH(boost::filesystem::path &path, *vFiles) {
+ FILE *file = fopen(path.string().c_str(), "rb");
+ if (file)
+ LoadExternalBlockFile(file);
+ }
+
+ // hardcoded $DATADIR/bootstrap.dat
+ filesystem::path pathBootstrap = GetDataDir() / "bootstrap.dat";
+ if (filesystem::exists(pathBootstrap)) {
+ uiInterface.InitMessage(_("Importing bootstrap blockchain data file."));
+
+ FILE *file = fopen(pathBootstrap.string().c_str(), "rb");
+ if (file) {
+ filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old";
+ LoadExternalBlockFile(file);
+ RenameOver(pathBootstrap, pathBootstrapOld);
+ }
+ }
+
+ delete vFiles;
+
+ vnThreadsRunning[THREAD_IMPORT]--;
+}
+
+
@@ -2512,7 +2561,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
// Ask the first connected node for block updates
static int nAskedForBlocks = 0;
- if (!pfrom->fClient && !pfrom->fOneShot &&
+ if (!pfrom->fClient && !pfrom->fOneShot && !fImporting &&
(pfrom->nStartingHeight > (nBestHeight - 144)) &&
(pfrom->nVersion < NOBLKS_VERSION_START ||
pfrom->nVersion >= NOBLKS_VERSION_END) &&
@@ -2649,9 +2698,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
if (fDebug)
printf(" got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new");
- if (!fAlreadyHave)
- pfrom->AskFor(inv);
- else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) {
+ if (!fAlreadyHave) {
+ if (!fImporting)
+ pfrom->AskFor(inv);
+ } else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) {
pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[inv.hash]));
} else if (nInv == nLastBlock) {
// In case we are on a very long side-chain, it is possible that we already have
diff --git a/src/main.h b/src/main.h
index 68302b85ac..ea71baf902 100644
--- a/src/main.h
+++ b/src/main.h
@@ -68,6 +68,7 @@ extern int64 nTimeBestReceived;
extern CCriticalSection cs_setpwalletRegistered;
extern std::set<CWallet*> setpwalletRegistered;
extern unsigned char pchMessageStart[4];
+extern bool fImporting;
// Settings
extern int64 nTransactionFee;
@@ -92,7 +93,7 @@ void PrintBlockTree();
CBlockIndex* FindBlockByHeight(int nHeight);
bool ProcessMessages(CNode* pfrom);
bool SendMessages(CNode* pto, bool fSendTrickle);
-bool LoadExternalBlockFile(FILE* fileIn);
+void ThreadImport(void *parg);
void GenerateBitcoins(bool fGenerate, CWallet* pwallet);
CBlock* CreateNewBlock(CReserveKey& reservekey);
void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
diff --git a/src/net.h b/src/net.h
index 3717c4e634..5e1564f9ca 100644
--- a/src/net.h
+++ b/src/net.h
@@ -106,6 +106,7 @@ enum threadId
THREAD_ADDEDCONNECTIONS,
THREAD_DUMPADDRESS,
THREAD_RPCHANDLER,
+ THREAD_IMPORT,
THREAD_MAX
};
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 19a6a65a1b..0d269ea210 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -473,7 +473,7 @@ void BitcoinGUI::setNumConnections(int count)
void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks)
{
// don't show / hide progress bar and its label if we have no connection to the network
- if (!clientModel || clientModel->getNumConnections() == 0)
+ if (!clientModel || (clientModel->getNumConnections() == 0 && !clientModel->isImporting()))
{
progressBarLabel->setVisible(false);
progressBar->setVisible(false);
@@ -491,7 +491,7 @@ void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks)
if (strStatusBarWarnings.isEmpty())
{
- progressBarLabel->setText(tr("Synchronizing with network..."));
+ progressBarLabel->setText(tr(clientModel->isImporting() ? "Importing blocks..." : "Synchronizing with network..."));
progressBarLabel->setVisible(true);
progressBar->setFormat(tr("~%n block(s) remaining", "", nRemainingBlocks));
progressBar->setMaximum(nTotalBlocks);
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp
index b820d16abf..990b364a94 100644
--- a/src/qt/clientmodel.cpp
+++ b/src/qt/clientmodel.cpp
@@ -103,6 +103,11 @@ bool ClientModel::inInitialBlockDownload() const
return IsInitialBlockDownload();
}
+bool ClientModel::isImporting() const
+{
+ return fImporting;
+}
+
int ClientModel::getNumBlocksOfPeers() const
{
return GetNumBlocksOfPeers();
diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h
index 70d816ba9d..926390a07a 100644
--- a/src/qt/clientmodel.h
+++ b/src/qt/clientmodel.h
@@ -33,6 +33,8 @@ public:
bool isTestNet() const;
//! Return true if core is doing initial block download
bool inInitialBlockDownload() const;
+ //! Return true if core is importing blocks
+ bool isImporting() const;
//! Return conservative estimate of total number of blocks, or 0 if unknown
int getNumBlocksOfPeers() const;
//! Return warnings to be displayed in status bar