@@ -27,6 +27,7 @@ extern bool fExplorer;
2727extern unsigned int nScraperSleep;
2828extern unsigned int nActiveBeforeSB;
2929extern bool fScraperActive ;
30+ extern bool fQtActive ;
3031
3132void Scraper (bool bSingleShot = false );
3233void ScraperSubscriber ();
@@ -40,17 +41,29 @@ namespace {
4041// !
4142void ShowChainCorruptedMessage ()
4243{
43- uiInterface.ThreadSafeMessageBox (
44- _ (" WARNING: Blockchain data may be corrupted.\n\n "
45- " Gridcoin detected bad index entries. This may occur because of an "
46- " unexpected exit, a power failure, or a late software upgrade.\n\n "
47- " Please exit Gridcoin, open the data directory, and delete:\n "
48- " - the blk****.dat files\n "
49- " - the txleveldb folder\n\n "
50- " Your wallet will re-download the blockchain. Your balance may "
51- " appear incorrect until the synchronization finishes.\n " ),
52- " Gridcoin" ,
53- CClientUIInterface::BTN_OK | CClientUIInterface::MODAL);
44+ fResetBlockchainRequest = true ;
45+
46+ if (fQtActive ) {
47+ uiInterface.ThreadSafeMessageBox (
48+ _ (" ERROR: Checkpoint mismatch: Blockchain data may be corrupted.\n\n "
49+ " Gridcoin detected bad index entries. This may occur because of a "
50+ " late software upgrade, unexpected exit, or a power failure. "
51+ " Your blockchain data is being reset and your wallet will resync "
52+ " from genesis when you restart. Your balance may appear incorrect "
53+ " until the synchronization finishes." ),
54+ " Gridcoin" ,
55+ CClientUIInterface::BTN_OK | CClientUIInterface::MODAL);
56+ } else {
57+ uiInterface.ThreadSafeMessageBox (
58+ _ (" ERROR: Checkpoint mismatch: Blockchain data may be corrupted.\n\n "
59+ " Gridcoin detected bad index entries. This may occur because of a "
60+ " late software upgrade, unexpected exit, or a power failure. "
61+ " Please run gridcoinresearchd with the -resetblockchaindata "
62+ " parameter. Your wallet will re-download the blockchain. Your "
63+ " balance may appear incorrect until the synchronization finishes." ),
64+ " Gridcoin" ,
65+ CClientUIInterface::BTN_OK | CClientUIInterface::MODAL);
66+ }
5467}
5568
5669// !
@@ -361,20 +374,23 @@ void InitializeExplorerFeatures()
361374// ! whether the index contains invalid state caused by an unclean shutdown.
362375// ! This condition was originally detected by an assertion in a routine for
363376// ! stake modifier checksum verification. Because Gridcoin removed modifier
364- // ! checksums and checkpoints , we reinstate that assertion here as a formal
365- // ! inspection .
377+ // ! checksums, we reinstate that assertion here as a formal inspection done
378+ // ! at initialization before the VerifyCheckpoints .
366379// !
367380// ! This function checks that no block index entries contain a null pointer
368381// ! to a previous block. The symptom may indicate a deeper problem that can
369382// ! be resolved by tuning disk synchronization in LevelDB. Until then, this
370383// ! heuristic has proven itself to be effective for identifying a corrupted
371- // ! database.
384+ // ! database. This type of error has not been seen in the wild in several
385+ // ! years as of Gridcoin 5.4.7.0, but is retained for thoroughness.
372386// !
373- void CheckBlockIndexJob ()
387+ bool CheckBlockIndex ()
374388{
375389 LogPrintf (" Gridcoin: checking block index..." );
390+ uiInterface.InitMessage (_ (" Checking block index..." ));
376391
377- bool corrupted = false ;
392+ // Block index integrity status
393+ bool status = true ;
378394
379395 if (pindexGenesisBlock) {
380396 LOCK (cs_main);
@@ -383,18 +399,20 @@ void CheckBlockIndexJob()
383399 const CBlockIndex* const pindex = index_pair.second ;
384400
385401 if (!pindex || !(pindex->pprev || pindex == pindexGenesisBlock)) {
386- corrupted = true ;
402+ status = false ;
387403 break ;
388404 }
389405 }
390406 }
391407
392- if (!corrupted ) {
408+ if (status ) {
393409 LogPrintf (" Gridcoin: block index is clean" );
394- return ;
410+ return status ;
395411 }
396412
397413 ShowChainCorruptedMessage ();
414+
415+ return status;
398416}
399417
400418// !
@@ -466,11 +484,8 @@ void ScheduleRegistriesPassivation(CScheduler& scheduler)
466484{
467485 // Run registry database passivation every 5 minutes. This is a very thin call most of the time.
468486 // Please see the PassivateDB function and passivate_db.
469- // TODO: Turn into a loop using extension of RegistryBookmarks
470- scheduler.scheduleEvery (BeaconRegistry::RunDBPassivation, std::chrono::minutes{5 });
471- scheduler.scheduleEvery (ScraperRegistry::RunDBPassivation, std::chrono::minutes{5 });
472- scheduler.scheduleEvery (ProtocolRegistry::RunDBPassivation, std::chrono::minutes{5 });
473- scheduler.scheduleEvery (Whitelist::RunDBPassivation, std::chrono::minutes{5 });
487+
488+ scheduler.scheduleEvery (RunDBPassivation, std::chrono::minutes{5 });
474489}
475490} // Anonymous namespace
476491
@@ -490,6 +505,9 @@ bool GRC::Initialize(ThreadHandlerPtr threads, CBlockIndex* pindexBest)
490505{
491506 LogPrintf (" Gridcoin: initializing..." );
492507
508+ if (!CheckBlockIndex ()) {
509+ return false ;
510+ }
493511 if (!VerifyCheckpoints (pindexBest)) {
494512 return false ;
495513 }
@@ -518,8 +536,6 @@ void GRC::CloseResearcherRegistryFile()
518536
519537void GRC::ScheduleBackgroundJobs (CScheduler& scheduler)
520538{
521- scheduler.schedule (CheckBlockIndexJob, std::chrono::system_clock::now ());
522-
523539 // Primitive, but this is what the scraper does in the scraper housekeeping
524540 // loop. It checks to see if the logs need to be archived by default every
525541 // 5 mins. Note that passing false to the archive function means that if we
@@ -589,3 +605,13 @@ skip:;
589605 return true ;
590606}
591607
608+ void GRC::RunDBPassivation ()
609+ {
610+ LOCK (cs_main);
611+
612+ for (const auto & contract_type : RegistryBookmarks::CONTRACT_TYPES_WITH_REG_DB) {
613+ Registry& registry = RegistryBookmarks::GetRegistryWithDB (contract_type);
614+
615+ registry.PassivateDB ();
616+ }
617+ }
0 commit comments