Skip to content

Commit 0d71c37

Browse files
authored
Merge pull request #2250 from jamescowens/fix_snapshot_download_4
qt: Fix crash during download snapshot on macOS
2 parents fa1c643 + 224ac4f commit 0d71c37

File tree

5 files changed

+169
-87
lines changed

5 files changed

+169
-87
lines changed

src/gridcoin/scraper/http.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,8 @@ void Http::DownloadSnapshot()
311311

312312
fs::path destination = GetDataDir() / "snapshot.zip";
313313

314+
LogPrint(BCLog::LogFlags::VERBOSE, "INFO: %s: Downloading snapshot to %s.", __func__, destination.string());
315+
314316
ScopedFile fp(fsbridge::fopen(destination, "wb"), &fclose);
315317

316318
if (!fp)

src/gridcoin/upgrade.cpp

Lines changed: 81 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -201,10 +201,6 @@ void Upgrade::SnapshotMain()
201201

202202
while (!DownloadStatus.GetSnapshotDownloadComplete())
203203
{
204-
LogPrintf("INFO: %s: DownloadStatus.GetSnapshotDownloadComplete() = %i",
205-
__func__,
206-
DownloadStatus.GetSnapshotDownloadComplete());
207-
208204
if (DownloadStatus.GetSnapshotDownloadFailed())
209205
{
210206
WorkerMainThread.interrupt();
@@ -234,10 +230,6 @@ void Upgrade::SnapshotMain()
234230

235231
while (!DownloadStatus.GetSHA256SUMComplete())
236232
{
237-
LogPrintf("INFO: %s: DownloadStatus.GetSHA256SUMComplete() = %i",
238-
__func__,
239-
DownloadStatus.GetSHA256SUMComplete());
240-
241233
if (DownloadStatus.GetSHA256SUMFailed())
242234
{
243235
WorkerMainThread.interrupt();
@@ -320,7 +312,7 @@ void Upgrade::WorkerMain(Progress& progress)
320312
// The "steps" are triggered in SnapshotMain but processed here in this switch statement.
321313
bool finished = false;
322314

323-
while (!finished)
315+
while (!finished && !fCancelOperation)
324316
{
325317
boost::this_thread::interruption_point();
326318

@@ -386,13 +378,14 @@ void Upgrade::DownloadSnapshot()
386378
}
387379
catch(std::runtime_error& e)
388380
{
389-
LogPrintf("Snapshot Downloader: Exception occurred while attempting to download snapshot (%s)", e.what());
381+
error("%s: Exception occurred while attempting to download snapshot (%s)", __func__, e.what());
390382

391383
DownloadStatus.SetSnapshotDownloadFailed(true);
384+
385+
return;
392386
}
393387

394-
LogPrintf("INFO %s: Snapshot download complete: DownloadStatus.GetSnapshotDownloadComplete() = %i",
395-
__func__, DownloadStatus.GetSnapshotDownloadComplete());
388+
LogPrint(BCLog::LogFlags::VERBOSE, "INFO: %s: Snapshot download complete.", __func__);
396389

397390
DownloadStatus.SetSnapshotDownloadComplete(true);
398391

@@ -411,13 +404,17 @@ void Upgrade::VerifySHA256SUM()
411404
}
412405
catch (std::runtime_error& e)
413406
{
414-
LogPrintf("Snapshot (VerifySHA256SUM): Exception occurred while attempting to retrieve snapshot SHA256SUM (%s)",
415-
e.what());
407+
error("%s: Exception occurred while attempting to retrieve snapshot SHA256SUM (%s)",
408+
__func__, e.what());
409+
410+
DownloadStatus.SetSHA256SUMFailed(true);
411+
412+
return;
416413
}
417414

418415
if (ServerSHA256SUM.empty())
419416
{
420-
LogPrintf("Snapshot (VerifySHA256SUM): Empty sha256sum returned from server");
417+
error("%s: Empty SHA256SUM returned from server.", __func__);
421418

422419
DownloadStatus.SetSHA256SUMFailed(true);
423420

@@ -433,11 +430,11 @@ void Upgrade::VerifySHA256SUM()
433430
unsigned char *buffer[32768];
434431
int bytesread = 0;
435432

436-
FILE *file = fsbridge::fopen(fileloc, "rb");
433+
CAutoFile file(fsbridge::fopen(fileloc, "rb"), SER_DISK, CLIENT_VERSION);
437434

438-
if (!file)
435+
if (file.IsNull())
439436
{
440-
LogPrintf("Snapshot (VerifySHA256SUM): Failed to open snapshot.zip");
437+
error("%s: Failed to open snapshot.zip.", __func__);
441438

442439
DownloadStatus.SetSHA256SUMFailed(true);
443440

@@ -447,7 +444,7 @@ void Upgrade::VerifySHA256SUM()
447444
unsigned int total_reads = fs::file_size(fileloc) / sizeof(buffer) + 1;
448445

449446
unsigned int read_count = 0;
450-
while ((bytesread = fread(buffer, 1, sizeof(buffer), file)))
447+
while ((bytesread = fread(buffer, 1, sizeof(buffer), file.Get())))
451448
{
452449
SHA256_Update(&ctx, buffer, bytesread);
453450
++read_count;
@@ -464,18 +461,19 @@ void Upgrade::VerifySHA256SUM()
464461

465462
std::string FileSHA256SUM = {mdString};
466463

467-
fclose(file);
468-
469464
if (ServerSHA256SUM == FileSHA256SUM)
470465
{
466+
LogPrint(BCLog::LogFlags::VERBOSE, "INFO %s: SHA256SUM verification successful.", __func__);
467+
468+
DownloadStatus.SetSHA256SUMProgress(100);
471469
DownloadStatus.SetSHA256SUMComplete(true);
472470

473471
return;
474472
}
475473
else
476474
{
477-
LogPrintf("Snapshot (VerifySHA256SUM): Mismatch of sha256sum of snapshot.zip (Server = %s / File = %s)",
478-
ServerSHA256SUM, FileSHA256SUM);
475+
error("%s: Mismatch of SHA256SUM of snapshot.zip (Server = %s / File = %s)",
476+
__func__, ServerSHA256SUM, FileSHA256SUM);
479477

480478
DownloadStatus.SetSHA256SUMFailed(true);
481479

@@ -487,11 +485,42 @@ void Upgrade::CleanupBlockchainData()
487485
{
488486
fs::path CleanupPath = GetDataDir();
489487

488+
// This is required because of problems with junction point handling in the boost filesystem library. Please see
489+
// https://github.com/boostorg/filesystem/issues/125. We are not quite ready to switch over to std::filesystem yet.
490+
// 1. I don't know whether the issue is fixed there, and
491+
// 2. Not all C++17 compilers have the filesystem headers, since this was merged from boost in 2017.
492+
//
493+
// I don't believe it is very common for Windows users to redirect the Gridcoin data directory with a junction point,
494+
// but it is certainly possible. We should handle it as gracefully as possible.
495+
if (fs::is_symlink(CleanupPath))
496+
{
497+
LogPrintf("INFO: %s: Data directory is a symlink.",
498+
__func__);
499+
500+
try
501+
{
502+
LogPrintf("INFO: %s: True path for the symlink is %s.", __func__, fs::read_symlink(CleanupPath).string());
503+
504+
CleanupPath = fs::read_symlink(CleanupPath);
505+
}
506+
catch (fs::filesystem_error &ex)
507+
{
508+
error("%s: The data directory symlink or junction point cannot be resolved to the true canonical path. "
509+
"This can happen on Windows. Please change the data directory specified to the actual true path "
510+
"using the -datadir=<path> option and try again.", __func__);
511+
512+
DownloadStatus.SetCleanupBlockchainDataFailed(true);
513+
514+
return;
515+
}
516+
}
517+
490518
unsigned int total_items = 0;
491519
unsigned int items = 0;
492520

493521
// We must delete previous blockchain data
494522
// txleveldb
523+
// accrual
495524
// blk*.dat
496525
fs::directory_iterator IterEnd;
497526

@@ -545,7 +574,7 @@ void Upgrade::CleanupBlockchainData()
545574
}
546575
catch (fs::filesystem_error &ex)
547576
{
548-
LogPrintf("%s: Exception occurred: %s", __func__, ex.what());
577+
error("%s: Exception occurred: %s", __func__, ex.what());
549578

550579
DownloadStatus.SetCleanupBlockchainDataFailed(true);
551580

@@ -554,6 +583,8 @@ void Upgrade::CleanupBlockchainData()
554583

555584
if (!total_items)
556585
{
586+
// Nothing to clean up!
587+
557588
DownloadStatus.SetCleanupBlockchainDataComplete(true);
558589

559590
return;
@@ -640,16 +671,17 @@ void Upgrade::CleanupBlockchainData()
640671
}
641672
}
642673
}
643-
644674
catch (fs::filesystem_error &ex)
645675
{
646-
LogPrintf("%s: Exception occurred: %s", __func__, ex.what());
676+
error("%s: Exception occurred: %s", __func__, ex.what());
647677

648678
DownloadStatus.SetCleanupBlockchainDataFailed(true);
649679

650680
return;
651681
}
652682

683+
LogPrint(BCLog::LogFlags::VERBOSE, "INFO: %s: Prior blockchain data cleanup successful.", __func__);
684+
653685
DownloadStatus.SetCleanupBlockchainDataProgress(100);
654686
DownloadStatus.SetCleanupBlockchainDataComplete(true);
655687

@@ -660,33 +692,31 @@ void Upgrade::ExtractSnapshot()
660692
{
661693
try
662694
{
663-
fs::path archive_path = GetDataDir() / "snapshot.zip";
664-
FILE* archive_file = fsbridge::fopen(archive_path, "rb");
665-
666-
fs::path ExtractPath = GetDataDir();
667-
668695
zip_error_t* err = new zip_error_t;
669-
zip_error_init(err);
670-
671696
struct zip* ZipArchive;
672-
struct zip_stat ZipStat;
673-
long long totaluncompressedsize = 0;
674-
long long currentuncompressedsize = 0;
675-
int64_t lastupdated = GetAdjustedTime();
676697

677-
zip_source_t* zip_source = zip_source_filep_create(archive_file, 0, -1, err);
698+
std::string archive_file_string = (GetDataDir() / "snapshot.zip").string();
699+
const char* archive_file = archive_file_string.c_str();
678700

679-
ZipArchive = zip_open_from_source(zip_source, 0, err);
701+
int ze;
702+
703+
ZipArchive = zip_open(archive_file, 0, &ze);
704+
zip_error_init_with_code(err, ze);
680705

681706
if (ZipArchive == nullptr)
682707
{
683708
ExtractStatus.SetSnapshotExtractFailed(true);
684709

685-
LogPrintf("Snapshot (ExtractSnapshot): Error opening snapshot.zip: %s", zip_error_strerror(err));
710+
error("%s: Error opening snapshot.zip as zip archive: %s", __func__, zip_error_strerror(err));
686711

687712
return;
688713
}
689714

715+
fs::path ExtractPath = GetDataDir();
716+
struct zip_stat ZipStat;
717+
int64_t lastupdated = GetAdjustedTime();
718+
long long totaluncompressedsize = 0;
719+
long long currentuncompressedsize = 0;
690720
uint64_t entries = (uint64_t) zip_get_num_entries(ZipArchive, 0);
691721

692722
// Let's scan for total size uncompressed so we can do a detailed progress for the watching user
@@ -705,7 +735,7 @@ void Upgrade::ExtractSnapshot()
705735
{
706736
ExtractStatus.SetSnapshotZipInvalid(true);
707737

708-
LogPrintf("Snapshot (ExtractSnapshot): Error - snapshot.zip has no entries");
738+
error("%s: Error - snapshot.zip has no entries", __func__);
709739

710740
return;
711741
}
@@ -730,21 +760,21 @@ void Upgrade::ExtractSnapshot()
730760
{
731761
ExtractStatus.SetSnapshotExtractFailed(true);
732762

733-
LogPrintf("Snapshot (ExtractSnapshot): Error opening file %s within snapshot.zip", ZipStat.name);
763+
error("%s: Error opening file %s within snapshot.zip", __func__, ZipStat.name);
734764

735765
return;
736766
}
737767

738768

739769
fs::path ExtractFileString = ExtractPath / ZipStat.name;
740770

741-
FILE* ExtractFile = fsbridge::fopen(ExtractFileString, "wb");
771+
CAutoFile ExtractFile(fsbridge::fopen(ExtractFileString, "wb"), SER_DISK, CLIENT_VERSION);
742772

743-
if (!ExtractFile)
773+
if (ExtractFile.IsNull())
744774
{
745775
ExtractStatus.SetSnapshotExtractFailed(true);
746776

747-
LogPrintf("Snapshot (ExtractSnapshot): Error opening file %s on filesystem", ZipStat.name);
777+
error("%s: Error opening file %s on filesystem", __func__, ZipStat.name);
748778

749779
return;
750780
}
@@ -754,6 +784,7 @@ void Upgrade::ExtractSnapshot()
754784
while ((uint64_t) sum < ZipStat.size)
755785
{
756786
int64_t len = 0;
787+
// Note that using a buffer larger than this risks crashes on macOS.
757788
char Buf[256*1024];
758789

759790
boost::this_thread::interruption_point();
@@ -764,12 +795,12 @@ void Upgrade::ExtractSnapshot()
764795
{
765796
ExtractStatus.SetSnapshotExtractFailed(true);
766797

767-
LogPrintf("Snapshot (ExtractSnapshot): Failed to read zip buffer");
798+
error("%s: Failed to read zip buffer", __func__);
768799

769800
return;
770801
}
771802

772-
fwrite(Buf, 1, (uint64_t) len, ExtractFile);
803+
fwrite(Buf, 1, (uint64_t) len, ExtractFile.Get());
773804

774805
sum += len;
775806
currentuncompressedsize += len;
@@ -784,7 +815,6 @@ void Upgrade::ExtractSnapshot()
784815
}
785816
}
786817

787-
fclose(ExtractFile);
788818
zip_fclose(ZipFile);
789819
}
790820
}
@@ -794,7 +824,7 @@ void Upgrade::ExtractSnapshot()
794824
{
795825
ExtractStatus.SetSnapshotExtractFailed(true);
796826

797-
LogPrintf("Snapshot (ExtractSnapshot): Failed to close snapshot.zip");
827+
error("%s: Failed to close snapshot.zip", __func__);
798828

799829
return;
800830
}
@@ -816,6 +846,8 @@ void Upgrade::ExtractSnapshot()
816846
return;
817847
}
818848

849+
LogPrint(BCLog::LogFlags::VERBOSE, "INFO: %s: Snapshot.zip extraction successful.", __func__);
850+
819851
ExtractStatus.SetSnapshotExtractProgress(100);
820852
ExtractStatus.SetSnapshotExtractComplete(true);
821853
return;

src/qt/bitcoingui.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -708,8 +708,6 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel)
708708
#ifndef Q_OS_MAC
709709
qApp->setWindowIcon(QPixmap(":/images/gridcoin_testnet"));
710710
setWindowIcon(QPixmap(":/images/gridcoin_testnet"));
711-
#else
712-
MacDockIconHandler::instance()->setIcon(QPixmap(":/images/gridcoin_testnet"));
713711
#endif
714712
if(trayIcon)
715713
{
@@ -843,6 +841,14 @@ void BitcoinGUI::createTrayIconMenu()
843841
// Note: On Mac, the dock icon is used to provide the tray's functionality.
844842
MacDockIconHandler *dockIconHandler = MacDockIconHandler::instance();
845843
dockIconHandler->setMainWindow((QMainWindow *)this);
844+
845+
// We have to set up the icons here late for the macOS
846+
if (this->clientModel && this->clientModel->isTestNet()) {
847+
dockIconHandler->setIcon(QPixmap(":/images/gridcoin_testnet"));
848+
} else {
849+
dockIconHandler->setIcon(QPixmap(":/images/gridcoin"));
850+
}
851+
846852
trayIconMenu = dockIconHandler->dockMenu();
847853
#endif
848854

0 commit comments

Comments
 (0)