Skip to content

Commit

Permalink
Merge pull request #2093 from iFoggz/snapshotchanges
Browse files Browse the repository at this point in the history
Changes for snapshotdownload and add feature sync from zero
  • Loading branch information
jamescowens committed Apr 11, 2021
2 parents 19fa6b8 + 3078813 commit 076e5b6
Show file tree
Hide file tree
Showing 12 changed files with 282 additions and 19 deletions.
5 changes: 3 additions & 2 deletions src/gridcoin/gridcoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,12 +406,12 @@ void ScheduleUpdateChecks(CScheduler& scheduler)
LogPrintf("Gridcoin: checking for updates every %" PRId64 " hours", hours);

scheduler.scheduleEvery([]{
g_UpdateChecker->CheckForLatestUpdate();
g_UpdateChecker->ScheduledUpdateCheck();
}, hours * 60 * 60 * 1000);

// Schedule a start-up check one minute from now:
scheduler.scheduleFromNow([]{
g_UpdateChecker->CheckForLatestUpdate();
g_UpdateChecker->ScheduledUpdateCheck();
}, 60 * 1000);
}

Expand All @@ -429,6 +429,7 @@ void ScheduleBeaconDBPassivation(CScheduler& scheduler)

std::unique_ptr<Upgrade> g_UpdateChecker;
bool fSnapshotRequest = false;
bool fResetBlockchainRequest = false;

// -----------------------------------------------------------------------------
// Functions
Expand Down
88 changes: 74 additions & 14 deletions src/gridcoin/upgrade.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,17 @@ Upgrade::Upgrade()
ExtractStatus.SnapshotExtractProgress = 0;
}

bool Upgrade::CheckForLatestUpdate(bool ui_dialog, std::string client_message_out)
void Upgrade::ScheduledUpdateCheck()
{
std::string VersionResponse = "";

CheckForLatestUpdate(VersionResponse);
}

bool Upgrade::CheckForLatestUpdate(std::string& client_message_out, bool ui_dialog, bool snapshotrequest)
{
// If testnet skip this || If the user changes this to disable while wallet running just drop out of here now. (need a way to remove items from scheduler)
if (fTestNet || GetBoolArg("-disableupdatecheck", false))
if (fTestNet || (GetBoolArg("-disableupdatecheck", false) && !snapshotrequest))
return false;

Http VersionPull;
Expand All @@ -59,14 +66,12 @@ bool Upgrade::CheckForLatestUpdate(bool ui_dialog, std::string client_message_ou

catch (const std::runtime_error& e)
{
LogPrintf("Update Checker: Exception occurred while checking for latest update. (%s)", e.what());

return false;
return error("%s: Exception occurred while checking for latest update. (%s)", __func__, e.what());
}

if (VersionResponse.empty())
{
LogPrintf("Update Checker: No Response from github");
LogPrintf("%s: No Response from github", __func__);

return false;
}
Expand All @@ -91,7 +96,7 @@ bool Upgrade::CheckForLatestUpdate(bool ui_dialog, std::string client_message_ou

catch (std::exception& ex)
{
LogPrintf("Update Checker: Exception occurred while parsing json response (%s)", ex.what());
LogPrintf("%s: Exception occurred while parsing json response (%s)", __func__, ex.what());

return false;
}
Expand All @@ -118,7 +123,7 @@ bool Upgrade::CheckForLatestUpdate(bool ui_dialog, std::string client_message_ou

if (GithubVersion.size() != 4)
{
LogPrintf("Update Check: Got malformed version (%s)", GithubReleaseData);
LogPrintf("%s: Got malformed version (%s)", __func__, GithubReleaseData);

return false;
}
Expand All @@ -144,7 +149,7 @@ bool Upgrade::CheckForLatestUpdate(bool ui_dialog, std::string client_message_ou
}
catch (std::exception& ex)
{
LogPrintf("Update Check: Exception occurred checking client version against github version (%s)", ToString(ex.what()));
LogPrintf("%s: Exception occurred checking client version against github version (%s)", __func__, ToString(ex.what()));

return false;
}
Expand All @@ -156,17 +161,17 @@ bool Upgrade::CheckForLatestUpdate(bool ui_dialog, std::string client_message_ou
client_message_out.append(_("Github version: ") + GithubReleaseData + "\r\n");
client_message_out.append(_("This update is ") + GithubReleaseType + "\r\n\r\n");

// For snapshot requests we will handle things differently after this point
if (snapshotrequest && NewMandatory)
return NewVersion;

if (NewMandatory)
{
client_message_out.append(_("WARNING: A mandatory release is available. Please upgrade as soon as possible.") + "\n");
}

std::string ChangeLog = GithubReleaseBody;

if (ui_dialog)
{
uiInterface.UpdateMessageBox(client_message_out, ChangeLog);
}

return NewVersion;
}
Expand All @@ -177,6 +182,18 @@ void Upgrade::SnapshotMain()
std::cout << _("Snapshot Process Has Begun.") << std::endl;
std::cout << _("Warning: Ending this process after Stage 2 will result in syncing from 0 or an incomplete/corrupted blockchain.") << std::endl << std::endl;

// Verify a mandatory release is not available before we continue to snapshot download.
std::string VersionResponse = "";

if (CheckForLatestUpdate(VersionResponse, false, true))
{
std::cout << this->ResetBlockchainMessages(UpdateAvailable) << std::endl;
std::cout << this->ResetBlockchainMessages(GithubResponse) << std::endl;
std::cout << VersionResponse << std::endl;

throw std::runtime_error(_("Failed to download snapshot as mandatory client is available for download."));
}

// Create a thread for snapshot to be downloaded
boost::thread SnapshotDownloadThread(std::bind(&Upgrade::DownloadSnapshot, this));

Expand Down Expand Up @@ -400,7 +417,7 @@ bool Upgrade::CleanupBlockchainData()

catch (fs::filesystem_error &ex)
{
LogPrintf("Snapshot (CleanupBlockchainData): Exception occurred: %s", ex.what());
LogPrintf("%s: Exception occurred: %s", __func__, ex.what());

return false;
}
Expand Down Expand Up @@ -571,3 +588,46 @@ void Upgrade::DeleteSnapshot()
LogPrintf("Snapshot Downloader: Exception occurred while attempting to delete snapshot (%s)", e.code().message());
}
}

bool Upgrade::ResetBlockchainData()
{
return CleanupBlockchainData();
}

std::string Upgrade::ResetBlockchainMessages(ResetBlockchainMsg _msg)
{
std::stringstream stream;

switch (_msg) {
case CleanUp:
{
stream << _("Datadir: ");
stream << GetDataDir().string();
stream << "\r\n\r\n";
stream << _("Due to the failure to delete the blockchain data you will be required to manually delete the data before starting your wallet.");
stream << "\r\n";
stream << _("Failure to do so will result in undefined behaviour or failure to start wallet.");
stream << "\r\n\r\n";
stream << _("You will need to delete the following.");
stream << "\r\n\r\n";
stream << _("Files:");
stream << "\r\n";
stream << "blk000*.dat";
stream << "\r\n\r\n";
stream << _("Directories:");
stream << "\r\n";
stream << "txleveldb";
stream << "\r\n";
stream << "accrual";

break;
}

case UpdateAvailable: stream << _("Unable to download a snapshot, as the wallet has detected that a new mandatory version is available for install. The mandatory upgrade must be installed before the snapshot can be downloaded and applied."); break;
case GithubResponse: stream << _("Latest Version github data response:"); break;
}

const std::string& output = stream.str();

return output;
}
30 changes: 29 additions & 1 deletion src/gridcoin/upgrade.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,24 @@ class Upgrade
//!
Upgrade();

//!
//! \brief Enum for determining the type of message to be returned for ResetBlockchainData functions
//!
enum ResetBlockchainMsg {
CleanUp,
UpdateAvailable,
GithubResponse
};

//!
//! \brief Scheduler call to CheckForLatestUpdate
//!
static void ScheduledUpdateCheck();

//!
//! \brief Check for latest updates on github.
//!
static bool CheckForLatestUpdate(bool ui_dialog = true, std::string client_message_out = "");
static bool CheckForLatestUpdate(std::string& client_message_out, bool ui_dialog = true, bool snapshotrequest = false);

//!
//! \brief Function that will be threaded to download snapshot
Expand Down Expand Up @@ -85,6 +99,20 @@ class Upgrade
//! \brief Small function to delete the snapshot.zip file
//!
static void DeleteSnapshot();

//!
//! \brief Small function to allow wallet user to clear blockchain data and sync from 0 while keeping a clean look
//!
//! \returns Bool on the success of blockchain cleanup
//!
static bool ResetBlockchainData();

//!
//! \brief Small function to return translated messages.
//!
//! \returns String containing message.
//!
static std::string ResetBlockchainMessages(ResetBlockchainMsg _msg);
};

//!
Expand Down
39 changes: 39 additions & 0 deletions src/gridcoinresearchd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,14 @@ bool AppInit(int argc, char* argv[])
// Initialize logging as early as possible.
InitLogging();

// Make sure a user does not request snapshotdownload and resetblockchaindata at same time!
if (mapArgs.count("-snapshotdownload") && mapArgs.count("-resetblockchaindata"))
{
fprintf(stderr, "-snapshotdownload and -resetblockchaindata cannot be used in conjunction");

exit(1);
}

// Check to see if the user requested a snapshot and we are not running TestNet!
if (mapArgs.count("-snapshotdownload") && !mapArgs.count("-testnet"))
{
Expand Down Expand Up @@ -134,6 +142,37 @@ bool AppInit(int argc, char* argv[])
snapshot.DeleteSnapshot();
}

// Check to see if the user requested to reset blockchain data -- We allow reset blockchain data on testnet, but not a snapshot download.
if (mapArgs.count("-resetblockchaindata"))
{
GRC::Upgrade resetblockchain;

// Let's check make sure gridcoin is not already running in the data directory.
if (!LockDirectory(GetDataDir(), ".lock", false))
{
fprintf(stderr, "Cannot obtain a lock on data directory %s. Gridcoin is probably already running.", GetDataDir().string().c_str());

exit(1);
}

else
{
if (resetblockchain.ResetBlockchainData())
LogPrintf("ResetBlockchainData: success");

else
{
LogPrintf("ResetBlockchainData: failed to clean up blockchain data");

std::string inftext = resetblockchain.ResetBlockchainMessages(resetblockchain.CleanUp);

fprintf(stderr, "%s", inftext.c_str());

exit(1);
}
}
}

LogPrintf("AppInit");

fRet = AppInit2(threads);
Expand Down
3 changes: 2 additions & 1 deletion src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,8 @@ std::string HelpMessage()
" -snapshotsha256url=<url> " + _("Optional: URL for the snapshot.sha256 file (ex: https://sub.domain.com/location/snapshot.sha256)") + "\n"
" -disableupdatecheck " + _("Optional: Disable update checks by wallet") + "\n"
" -updatecheckinterval=<n> " + _("Optional: Check for updates every <n> hours (default: 120, minimum: 1)") + "\n"
" -updatecheckurl=<url> " + _("Optional: URL for the update version checks (ex: https://sub.domain.com/location/latest") + "\n";
" -updatecheckurl=<url> " + _("Optional: URL for the update version checks (ex: https://sub.domain.com/location/latest") + "\n"
" -resetblockchaindata " + _("Reset blockchain data. This argument will remove all previous blockchain data") + "\n";

return strUsage;
}
Expand Down
1 change: 1 addition & 0 deletions src/init.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ std::string VersionMessage();
std::string LogSomething();

extern bool fSnapshotRequest;
extern bool fResetBlockchainRequest;
#endif
51 changes: 51 additions & 0 deletions src/qt/bitcoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,14 @@ int main(int argc, char *argv[])
// Do this early as we don't want to bother initializing if we are just calling IPC
ipcScanRelay(argc, argv);

// Make sure a user does not request snapshotdownload and resetblockchaindata at same time!
if (mapArgs.count("-snapshotdownload") && mapArgs.count("-resetblockchaindata"))
{
LogPrintf("-snapshotdownload and -resetblockchaindata cannot be used in conjunction");

return EXIT_FAILURE;
}

// Run snapshot main if Gridcoin was started with the snapshot argument and we are not TestNet
if (mapArgs.count("-snapshotdownload") && !mapArgs.count("-testnet"))
{
Expand All @@ -378,6 +386,27 @@ int main(int argc, char *argv[])
snapshot.DeleteSnapshot();
}

// Check to see if the user requested to reset blockchain data -- We allow on testnet.
if (mapArgs.count("-resetblockchaindata"))
{
GRC::Upgrade resetblockchain;

if (resetblockchain.ResetBlockchainData())
LogPrintf("ResetBlockchainData: success");

else
{
LogPrintf("ResetBlockchainData: failed to clean up blockchain data");

std::string inftext = resetblockchain.ResetBlockchainMessages(resetblockchain.CleanUp);

ThreadSafeMessageBox(inftext, _("Gridcoin"), CClientUIInterface::OK | CClientUIInterface::MODAL);
QMessageBox::critical(nullptr, PACKAGE_NAME, QString::fromStdString(inftext));

return EXIT_FAILURE;
}
}

/** Start Qt as normal before it was moved into this function **/
StartGridcoinQt(argc, argv, app, optionsModel);

Expand Down Expand Up @@ -422,6 +451,28 @@ int main(int argc, char *argv[])
Snapshot.DeleteSnapshot();
}

// We received a request to remove blockchain data so client user can start to sync from 0
if (fResetBlockchainRequest)
{
UpgradeQt resetblockchain;

// Release LevelDB file handles on Windows so we can remove the old
// blockchain files:
//
// We should really close it in Shutdown() when the main application
// exits. Before we can do that, we need to solve an old outstanding
// conflict with the behavior of "-daemon" on Linux that prematurely
// closes the DB when the process forks.
//
CTxDB().Close();

if (resetblockchain.ResetBlockchain(app))
LogPrintf("ResetBlockchainData: success");

else
LogPrintf("ResetBlockchainData: failed");
}

return EXIT_SUCCESS;
}

Expand Down
Loading

0 comments on commit 076e5b6

Please sign in to comment.