Merge pull request #1880 from sipa/threadimport
Move external block import to separate thread
This commit is contained in:
commit
38ac953b9d
7 changed files with 70 additions and 27 deletions
22
src/init.cpp
22
src/init.cpp
|
@ -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
|
||||||
|
|
||||||
|
|
60
src/main.cpp
60
src/main.cpp
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -106,6 +106,7 @@ enum threadId
|
||||||
THREAD_ADDEDCONNECTIONS,
|
THREAD_ADDEDCONNECTIONS,
|
||||||
THREAD_DUMPADDRESS,
|
THREAD_DUMPADDRESS,
|
||||||
THREAD_RPCHANDLER,
|
THREAD_RPCHANDLER,
|
||||||
|
THREAD_IMPORT,
|
||||||
|
|
||||||
THREAD_MAX
|
THREAD_MAX
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue