|
|
@ -510,6 +510,21 @@ static void BlockNotifyCallback(bool initialSync, const CBlockIndex *pBlockIndex |
|
|
|
boost::thread t(runCommand, strCmd); // thread runs free
|
|
|
|
boost::thread t(runCommand, strCmd); // thread runs free
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool fHaveGenesis = false; |
|
|
|
|
|
|
|
static boost::mutex cs_GenesisWait; |
|
|
|
|
|
|
|
static CConditionVariable condvar_GenesisWait; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void BlockNotifyGenesisWait(bool, const CBlockIndex *pBlockIndex) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (pBlockIndex != NULL) { |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
boost::unique_lock<boost::mutex> lock_GenesisWait(cs_GenesisWait); |
|
|
|
|
|
|
|
fHaveGenesis = true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
condvar_GenesisWait.notify_all(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
struct CImportingNow |
|
|
|
struct CImportingNow |
|
|
|
{ |
|
|
|
{ |
|
|
|
CImportingNow() { |
|
|
|
CImportingNow() { |
|
|
@ -1286,7 +1301,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!fReindex) { |
|
|
|
if (!fReindex && chainActive.Tip() != NULL) { |
|
|
|
uiInterface.InitMessage(_("Rewinding blocks...")); |
|
|
|
uiInterface.InitMessage(_("Rewinding blocks...")); |
|
|
|
if (!RewindBlockIndex(chainparams)) { |
|
|
|
if (!RewindBlockIndex(chainparams)) { |
|
|
|
strLoadError = _("Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain"); |
|
|
|
strLoadError = _("Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain"); |
|
|
@ -1403,6 +1418,14 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) |
|
|
|
|
|
|
|
|
|
|
|
// ********************************************************* Step 10: import blocks
|
|
|
|
// ********************************************************* Step 10: import blocks
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Either install a handler to notify us when genesis activates, or set fHaveGenesis directly.
|
|
|
|
|
|
|
|
// No locking, as this happens before any background thread is started.
|
|
|
|
|
|
|
|
if (chainActive.Tip() == NULL) { |
|
|
|
|
|
|
|
uiInterface.NotifyBlockTip.connect(BlockNotifyGenesisWait); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
fHaveGenesis = true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (mapArgs.count("-blocknotify")) |
|
|
|
if (mapArgs.count("-blocknotify")) |
|
|
|
uiInterface.NotifyBlockTip.connect(BlockNotifyCallback); |
|
|
|
uiInterface.NotifyBlockTip.connect(BlockNotifyCallback); |
|
|
|
|
|
|
|
|
|
|
@ -1412,19 +1435,16 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) |
|
|
|
BOOST_FOREACH(const std::string& strFile, mapMultiArgs["-loadblock"]) |
|
|
|
BOOST_FOREACH(const std::string& strFile, mapMultiArgs["-loadblock"]) |
|
|
|
vImportFiles.push_back(strFile); |
|
|
|
vImportFiles.push_back(strFile); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
threadGroup.create_thread(boost::bind(&ThreadImport, vImportFiles)); |
|
|
|
threadGroup.create_thread(boost::bind(&ThreadImport, vImportFiles)); |
|
|
|
|
|
|
|
|
|
|
|
// Wait for genesis block to be processed
|
|
|
|
// Wait for genesis block to be processed
|
|
|
|
bool fHaveGenesis = false; |
|
|
|
{ |
|
|
|
while (!fHaveGenesis && !fRequestShutdown) { |
|
|
|
boost::unique_lock<boost::mutex> lock(cs_GenesisWait); |
|
|
|
{ |
|
|
|
while (!fHaveGenesis) { |
|
|
|
LOCK(cs_main); |
|
|
|
condvar_GenesisWait.wait(lock); |
|
|
|
fHaveGenesis = (chainActive.Tip() != NULL); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!fHaveGenesis) { |
|
|
|
|
|
|
|
MilliSleep(10); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
uiInterface.NotifyBlockTip.disconnect(BlockNotifyGenesisWait); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// ********************************************************* Step 11: start node
|
|
|
|
// ********************************************************* Step 11: start node
|
|
|
|