Use a signal to continue init after genesis activation

This commit is contained in:
Pieter Wuille 2016-07-22 15:57:25 +02:00
parent bbcb8fd884
commit 0fd2a33648
3 changed files with 35 additions and 12 deletions

View file

@ -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

View file

@ -4331,8 +4331,6 @@ bool InitBlockIndex(const CChainParams& chainparams)
CBlockIndex *pindex = AddToBlockIndex(block); CBlockIndex *pindex = AddToBlockIndex(block);
if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
return error("LoadBlockIndex(): genesis block not accepted"); return error("LoadBlockIndex(): genesis block not accepted");
if (!ActivateBestChain(state, chainparams, &block))
return error("LoadBlockIndex(): genesis block cannot be activated");
// Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data // Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data
return FlushStateToDisk(state, FLUSH_STATE_ALWAYS); return FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
} catch (const std::runtime_error& e) { } catch (const std::runtime_error& e) {

View file

@ -60,6 +60,11 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha
pcoinsdbview = new CCoinsViewDB(1 << 23, true); pcoinsdbview = new CCoinsViewDB(1 << 23, true);
pcoinsTip = new CCoinsViewCache(pcoinsdbview); pcoinsTip = new CCoinsViewCache(pcoinsdbview);
InitBlockIndex(chainparams); InitBlockIndex(chainparams);
{
CValidationState state;
bool ok = ActivateBestChain(state, chainparams);
BOOST_CHECK(ok);
}
nScriptCheckThreads = 3; nScriptCheckThreads = 3;
for (int i=0; i < nScriptCheckThreads-1; i++) for (int i=0; i < nScriptCheckThreads-1; i++)
threadGroup.create_thread(&ThreadScriptCheck); threadGroup.create_thread(&ThreadScriptCheck);