Browse Source

Merge #10919: Fix more init bugs.

e7539f8 Fix some broken init-time prints/constants (Matt Corallo)
13ab353 Check for empty coinsview instead of just-reset coinsview in init (Matt Corallo)
fce3f4f Fix resume-of-reindex-after-restart (Matt Corallo)
efac91e Always wait for threadGroup to exit in bitcoind shutdown (Matt Corallo)

Pull request description:

  This is a follow-on to #10758 to help move 10758 along. The first fixes a regression in master that was partially fixed in 10758, the second I'm not sure if its a regression or not, but its clearly a bug that should be fixed.

Tree-SHA512: aca7b97a97dca66e1a218a33cc6f4aa002292ff1bb0af64e35b81fbaa91b9504f2605375808b43e93a63fc73634ad079b30ef6c9f4ba338d3b5f72d816dfeaff
0.15
Wladimir J. van der Laan 7 years ago
parent
commit
c1c671feb1
No known key found for this signature in database
GPG Key ID: 1E4AED62986CD25D
  1. 4
      src/bitcoind.cpp
  2. 20
      src/init.cpp
  3. 2
      src/test/test_bitcoin.cpp
  4. 1
      src/validation.cpp

4
src/bitcoind.cpp

@ -176,9 +176,7 @@ bool AppInit(int argc, char* argv[])
if (!fRet) if (!fRet)
{ {
Interrupt(threadGroup); Interrupt(threadGroup);
// threadGroup.join_all(); was left out intentionally here, because we didn't re-test all of threadGroup.join_all();
// the startup-failure cases to make sure they don't result in a hang due to some
// thread-blocking-waiting-for-another-thread-during-startup case
} else { } else {
WaitForShutdown(&threadGroup); WaitForShutdown(&threadGroup);
} }

20
src/init.cpp

@ -1400,9 +1400,9 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
delete pcoinscatcher; delete pcoinscatcher;
delete pblocktree; delete pblocktree;
pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex); pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReset);
if (fReindex) { if (fReset) {
pblocktree->WriteReindexing(true); pblocktree->WriteReindexing(true);
//If we're reindexing in prune mode, wipe away unusable block files and all undo data files //If we're reindexing in prune mode, wipe away unusable block files and all undo data files
if (fPruneMode) if (fPruneMode)
@ -1414,6 +1414,8 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
// LoadBlockIndex will load fTxIndex from the db, or set it if // LoadBlockIndex will load fTxIndex from the db, or set it if
// we're reindexing. It will also load fHavePruned if we've // we're reindexing. It will also load fHavePruned if we've
// ever removed a block file from disk. // ever removed a block file from disk.
// Note that it also sets fReindex based on the disk flag!
// From here on out fReindex and fReset mean something different!
if (!LoadBlockIndex(chainparams)) { if (!LoadBlockIndex(chainparams)) {
strLoadError = _("Error loading block database"); strLoadError = _("Error loading block database");
break; break;
@ -1438,8 +1440,9 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
} }
// At this point blocktree args are consistent with what's on disk. // At this point blocktree args are consistent with what's on disk.
// If we're not mid-reindex (based on disk + args), add a genesis block on disk. // If we're not mid-reindex (based on disk + args), add a genesis block on disk
// This is called again in ThreadImport in the reindex completes. // (otherwise we use the one already on disk).
// This is called again in ThreadImport after the reindex completes.
if (!fReindex && !LoadGenesisBlock(chainparams)) { if (!fReindex && !LoadGenesisBlock(chainparams)) {
strLoadError = _("Error initializing block database"); strLoadError = _("Error initializing block database");
break; break;
@ -1448,7 +1451,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
// At this point we're either in reindex or we've loaded a useful // At this point we're either in reindex or we've loaded a useful
// block tree into mapBlockIndex! // block tree into mapBlockIndex!
pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex || fReindexChainState); pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReset || fReindexChainState);
pcoinscatcher = new CCoinsViewErrorCatcher(pcoinsdbview); pcoinscatcher = new CCoinsViewErrorCatcher(pcoinsdbview);
// If necessary, upgrade from older database format. // If necessary, upgrade from older database format.
@ -1467,7 +1470,8 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
// The on-disk coinsdb is now in a good state, create the cache // The on-disk coinsdb is now in a good state, create the cache
pcoinsTip = new CCoinsViewCache(pcoinscatcher); pcoinsTip = new CCoinsViewCache(pcoinscatcher);
if (!fReindex && !fReindexChainState) { bool is_coinsview_empty = fReset || fReindexChainState || pcoinsTip->GetBestBlock().IsNull();
if (!is_coinsview_empty) {
// LoadChainTip sets chainActive based on pcoinsTip's best block // LoadChainTip sets chainActive based on pcoinsTip's best block
if (!LoadChainTip(chainparams)) { if (!LoadChainTip(chainparams)) {
strLoadError = _("Error initializing block database"); strLoadError = _("Error initializing block database");
@ -1476,7 +1480,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
assert(chainActive.Tip() != NULL); assert(chainActive.Tip() != NULL);
} }
if (!fReindex) { if (!fReset) {
// Note that RewindBlockIndex MUST run even if we're about to -reindex-chainstate. // Note that RewindBlockIndex MUST run even if we're about to -reindex-chainstate.
// It both disconnects blocks based on chainActive, and drops block data in // It both disconnects blocks based on chainActive, and drops block data in
// mapBlockIndex based on lack of available witness data. // mapBlockIndex based on lack of available witness data.
@ -1487,7 +1491,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
} }
} }
if (!fReindex && !fReindexChainState) { if (!is_coinsview_empty) {
uiInterface.InitMessage(_("Verifying blocks...")); uiInterface.InitMessage(_("Verifying blocks..."));
if (fHavePruned && GetArg("-checkblocks", DEFAULT_CHECKBLOCKS) > MIN_BLOCKS_TO_KEEP) { if (fHavePruned && GetArg("-checkblocks", DEFAULT_CHECKBLOCKS) > MIN_BLOCKS_TO_KEEP) {
LogPrintf("Prune: pruned datadir may not have more than %d blocks; only checking available blocks", LogPrintf("Prune: pruned datadir may not have more than %d blocks; only checking available blocks",

2
src/test/test_bitcoin.cpp

@ -75,7 +75,7 @@ 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);
if (!LoadGenesisBlock(chainparams)) { if (!LoadGenesisBlock(chainparams)) {
throw std::runtime_error("InitBlockIndex failed."); throw std::runtime_error("LoadGenesisBlock failed.");
} }
{ {
CValidationState state; CValidationState state;

1
src/validation.cpp

@ -3916,7 +3916,6 @@ bool LoadGenesisBlock(const CChainParams& chainparams)
if (mapBlockIndex.count(chainparams.GenesisBlock().GetHash())) if (mapBlockIndex.count(chainparams.GenesisBlock().GetHash()))
return true; return true;
// Only add the genesis block if not reindexing (in which case we reuse the one already on disk)
try { try {
CBlock &block = const_cast<CBlock&>(chainparams.GenesisBlock()); CBlock &block = const_cast<CBlock&>(chainparams.GenesisBlock());
// Start new block file // Start new block file

Loading…
Cancel
Save