Merge pull request #1880 from sipa/threadimport

Move external block import to separate thread
This commit is contained in:
Jeff Garzik 2012-10-20 13:36:36 -07:00
commit 38ac953b9d
7 changed files with 70 additions and 27 deletions

View file

@ -776,29 +776,13 @@ bool AppInit2()
// ********************************************************* Step 9: import blocks // ********************************************************* Step 9: import blocks
std::vector<boost::filesystem::path> *vPath = new std::vector<boost::filesystem::path>();
if (mapArgs.count("-loadblock")) if (mapArgs.count("-loadblock"))
{ {
uiInterface.InitMessage(_("Importing blockchain data file."));
BOOST_FOREACH(string strFile, mapMultiArgs["-loadblock"]) BOOST_FOREACH(string strFile, mapMultiArgs["-loadblock"])
{ vPath->push_back(strFile);
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);
}
} }
NewThread(ThreadImport, vPath);
// ********************************************************* Step 10: load peers // ********************************************************* Step 10: load peers

View file

@ -38,6 +38,7 @@ CBigNum bnBestInvalidWork = 0;
uint256 hashBestChain = 0; uint256 hashBestChain = 0;
CBlockIndex* pindexBest = NULL; CBlockIndex* pindexBest = NULL;
int64 nTimeBestReceived = 0; int64 nTimeBestReceived = 0;
bool fImporting = false;
CMedianFilter<int> cPeerBlockCounts(5, 0); // Amount of blocks that other nodes claim to have 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; int nLoaded = 0;
{ {
LOCK(cs_main);
try { try {
CAutoFile blkdat(fileIn, SER_DISK, CLIENT_VERSION); CAutoFile blkdat(fileIn, SER_DISK, CLIENT_VERSION);
unsigned int nPos = 0; unsigned int nPos = 0;
@ -2288,6 +2288,7 @@ bool LoadExternalBlockFile(FILE* fileIn)
{ {
CBlock block; CBlock block;
blkdat >> block; blkdat >> block;
LOCK(cs_main);
if (ProcessBlock(NULL,&block)) if (ProcessBlock(NULL,&block))
{ {
nLoaded++; nLoaded++;
@ -2305,6 +2306,54 @@ bool LoadExternalBlockFile(FILE* fileIn)
return nLoaded > 0; 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 // Ask the first connected node for block updates
static int nAskedForBlocks = 0; static int nAskedForBlocks = 0;
if (!pfrom->fClient && !pfrom->fOneShot && if (!pfrom->fClient && !pfrom->fOneShot && !fImporting &&
(pfrom->nStartingHeight > (nBestHeight - 144)) && (pfrom->nStartingHeight > (nBestHeight - 144)) &&
(pfrom->nVersion < NOBLKS_VERSION_START || (pfrom->nVersion < NOBLKS_VERSION_START ||
pfrom->nVersion >= NOBLKS_VERSION_END) && pfrom->nVersion >= NOBLKS_VERSION_END) &&
@ -2649,9 +2698,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
if (fDebug) if (fDebug)
printf(" got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new"); printf(" got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new");
if (!fAlreadyHave) if (!fAlreadyHave) {
pfrom->AskFor(inv); if (!fImporting)
else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) { pfrom->AskFor(inv);
} else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) {
pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[inv.hash])); pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[inv.hash]));
} else if (nInv == nLastBlock) { } else if (nInv == nLastBlock) {
// In case we are on a very long side-chain, it is possible that we already have // In case we are on a very long side-chain, it is possible that we already have

View file

@ -68,6 +68,7 @@ extern int64 nTimeBestReceived;
extern CCriticalSection cs_setpwalletRegistered; extern CCriticalSection cs_setpwalletRegistered;
extern std::set<CWallet*> setpwalletRegistered; extern std::set<CWallet*> setpwalletRegistered;
extern unsigned char pchMessageStart[4]; extern unsigned char pchMessageStart[4];
extern bool fImporting;
// Settings // Settings
extern int64 nTransactionFee; extern int64 nTransactionFee;
@ -92,7 +93,7 @@ void PrintBlockTree();
CBlockIndex* FindBlockByHeight(int nHeight); CBlockIndex* FindBlockByHeight(int nHeight);
bool ProcessMessages(CNode* pfrom); bool ProcessMessages(CNode* pfrom);
bool SendMessages(CNode* pto, bool fSendTrickle); bool SendMessages(CNode* pto, bool fSendTrickle);
bool LoadExternalBlockFile(FILE* fileIn); void ThreadImport(void *parg);
void GenerateBitcoins(bool fGenerate, CWallet* pwallet); void GenerateBitcoins(bool fGenerate, CWallet* pwallet);
CBlock* CreateNewBlock(CReserveKey& reservekey); CBlock* CreateNewBlock(CReserveKey& reservekey);
void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce); void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);

View file

@ -106,6 +106,7 @@ enum threadId
THREAD_ADDEDCONNECTIONS, THREAD_ADDEDCONNECTIONS,
THREAD_DUMPADDRESS, THREAD_DUMPADDRESS,
THREAD_RPCHANDLER, THREAD_RPCHANDLER,
THREAD_IMPORT,
THREAD_MAX THREAD_MAX
}; };

View file

@ -473,7 +473,7 @@ void BitcoinGUI::setNumConnections(int count)
void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks) void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks)
{ {
// don't show / hide progress bar and its label if we have no connection to the network // 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); progressBarLabel->setVisible(false);
progressBar->setVisible(false); progressBar->setVisible(false);
@ -491,7 +491,7 @@ void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks)
if (strStatusBarWarnings.isEmpty()) if (strStatusBarWarnings.isEmpty())
{ {
progressBarLabel->setText(tr("Synchronizing with network...")); progressBarLabel->setText(tr(clientModel->isImporting() ? "Importing blocks..." : "Synchronizing with network..."));
progressBarLabel->setVisible(true); progressBarLabel->setVisible(true);
progressBar->setFormat(tr("~%n block(s) remaining", "", nRemainingBlocks)); progressBar->setFormat(tr("~%n block(s) remaining", "", nRemainingBlocks));
progressBar->setMaximum(nTotalBlocks); progressBar->setMaximum(nTotalBlocks);

View file

@ -103,6 +103,11 @@ bool ClientModel::inInitialBlockDownload() const
return IsInitialBlockDownload(); return IsInitialBlockDownload();
} }
bool ClientModel::isImporting() const
{
return fImporting;
}
int ClientModel::getNumBlocksOfPeers() const int ClientModel::getNumBlocksOfPeers() const
{ {
return GetNumBlocksOfPeers(); return GetNumBlocksOfPeers();

View file

@ -33,6 +33,8 @@ public:
bool isTestNet() const; bool isTestNet() const;
//! Return true if core is doing initial block download //! Return true if core is doing initial block download
bool inInitialBlockDownload() const; 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 //! Return conservative estimate of total number of blocks, or 0 if unknown
int getNumBlocksOfPeers() const; int getNumBlocksOfPeers() const;
//! Return warnings to be displayed in status bar //! Return warnings to be displayed in status bar