@@ -485,9 +485,9 @@ void Upgrade::VerifySHA256SUM()
485
485
}
486
486
}
487
487
488
- void Upgrade::CleanupBlockchainData ( )
488
+ bool Upgrade::GetActualCleanupPath (fs::path& actual_cleanup_path )
489
489
{
490
- fs::path CleanupPath = GetDataDir ();
490
+ actual_cleanup_path = GetDataDir ();
491
491
492
492
// This is required because of problems with junction point handling in the boost filesystem library. Please see
493
493
// https://github.com/boostorg/filesystem/issues/125. We are not quite ready to switch over to std::filesystem yet.
@@ -496,16 +496,16 @@ void Upgrade::CleanupBlockchainData()
496
496
//
497
497
// I don't believe it is very common for Windows users to redirect the Gridcoin data directory with a junction point,
498
498
// but it is certainly possible. We should handle it as gracefully as possible.
499
- if (fs::is_symlink (CleanupPath ))
499
+ if (fs::is_symlink (actual_cleanup_path ))
500
500
{
501
501
LogPrintf (" INFO: %s: Data directory is a symlink." ,
502
502
__func__);
503
503
504
504
try
505
505
{
506
- LogPrintf (" INFO: %s: True path for the symlink is %s." , __func__, fs::read_symlink (CleanupPath ).string ());
506
+ LogPrintf (" INFO: %s: True path for the symlink is %s." , __func__, fs::read_symlink (actual_cleanup_path ).string ());
507
507
508
- CleanupPath = fs::read_symlink (CleanupPath );
508
+ actual_cleanup_path = fs::read_symlink (actual_cleanup_path );
509
509
}
510
510
catch (fs::filesystem_error &ex)
511
511
{
@@ -515,10 +515,19 @@ void Upgrade::CleanupBlockchainData()
515
515
516
516
DownloadStatus.SetCleanupBlockchainDataFailed (true );
517
517
518
- return ;
518
+ return false ;
519
519
}
520
520
}
521
521
522
+ return true ;
523
+ }
524
+
525
+ void Upgrade::CleanupBlockchainData (bool include_blockchain_data_files)
526
+ {
527
+ fs::path CleanupPath;
528
+
529
+ if (!GetActualCleanupPath (CleanupPath)) return ;
530
+
522
531
unsigned int total_items = 0 ;
523
532
unsigned int items = 0 ;
524
533
@@ -559,7 +568,7 @@ void Upgrade::CleanupBlockchainData()
559
568
continue ;
560
569
}
561
570
562
- else if (fs::is_regular_file (*Iter))
571
+ else if (fs::is_regular_file (*Iter) && include_blockchain_data_files )
563
572
{
564
573
size_t FileLoc = Iter->path ().filename ().string ().find (" blk" );
565
574
@@ -648,7 +657,7 @@ void Upgrade::CleanupBlockchainData()
648
657
continue ;
649
658
}
650
659
651
- else if (fs::is_regular_file (*Iter))
660
+ else if (fs::is_regular_file (*Iter) && include_blockchain_data_files )
652
661
{
653
662
size_t FileLoc = Iter->path ().filename ().string ().find (" blk" );
654
663
@@ -875,13 +884,126 @@ void Upgrade::DeleteSnapshot()
875
884
}
876
885
}
877
886
878
- bool Upgrade::ResetBlockchainData ()
887
+ bool Upgrade::ResetBlockchainData (bool include_blockchain_data_files )
879
888
{
880
- CleanupBlockchainData ();
889
+ CleanupBlockchainData (include_blockchain_data_files );
881
890
882
891
return (DownloadStatus.GetCleanupBlockchainDataComplete () && !DownloadStatus.GetCleanupBlockchainDataFailed ());
883
892
}
884
893
894
+ bool Upgrade::MoveBlockDataFiles (std::set<std::pair<fs::path, uintmax_t >>& block_data_files)
895
+ {
896
+ fs::path cleanup_path;
897
+
898
+ if (!GetActualCleanupPath (cleanup_path)) return false ;
899
+
900
+ fs::directory_iterator IterEnd;
901
+
902
+ try {
903
+ for (fs::directory_iterator Iter (cleanup_path); Iter != IterEnd; ++Iter) {
904
+ if (fs::is_regular_file (*Iter)) {
905
+ size_t FileLoc = Iter->path ().filename ().string ().find (" blk" );
906
+
907
+ if (FileLoc != std::string::npos) {
908
+ std::string filetocheck = Iter->path ().filename ().string ();
909
+
910
+ // Check it ends with .dat and starts with blk
911
+ if (filetocheck.substr (0 , 3 ) == " blk" && filetocheck.substr (filetocheck.length () - 4 , 4 ) == " .dat" ) {
912
+ fs::path new_name = *Iter;
913
+ new_name.replace_extension (" .dat.orig" );
914
+
915
+ uintmax_t file_size = fs::file_size (Iter->path ());
916
+
917
+ // Rename with orig as the extension, because ProcessBlock will load blocks into a new block data
918
+ // file.
919
+ fs::rename (*Iter, new_name);
920
+ block_data_files.insert (std::make_pair (new_name, file_size));
921
+ }
922
+ }
923
+ }
924
+ }
925
+ } catch (fs::filesystem_error &ex) {
926
+ error (" %s: Exception occurred: %s. Failed to rename block data files to blk*.dat.orig in preparation for "
927
+ " reindexing." , __func__, ex.what ());
928
+
929
+ return false ;
930
+ }
931
+
932
+ return true ;
933
+ }
934
+
935
+ bool Upgrade::ReindexBlockchainData (std::set<std::pair<fs::path, uintmax_t >>& block_data_files)
936
+ {
937
+ bool successful = true ;
938
+
939
+ uintmax_t total_size = 0 ;
940
+ uintmax_t cumulative_size = 0 ;
941
+
942
+ for (const auto & iter : block_data_files) {
943
+ total_size += iter.second ;
944
+ }
945
+
946
+ if (!total_size) return false ;
947
+
948
+ try {
949
+ for (const auto & iter : block_data_files) {
950
+
951
+ unsigned int percent_start = cumulative_size * (uintmax_t ) 100 / total_size;
952
+
953
+ cumulative_size += iter.second ;
954
+
955
+ unsigned int percent_end = cumulative_size * (uintmax_t ) 100 / total_size;
956
+
957
+ FILE *block_data_file = fsbridge::fopen (iter.first , " rb" );
958
+
959
+ LogPrintf (" INFO: %s: Loading blocks from %s." , __func__, iter.first .filename ().string ());
960
+
961
+ if (!LoadExternalBlockFile (block_data_file, iter.second , percent_start, percent_end)) {
962
+ successful = false ;
963
+
964
+ break ;
965
+ }
966
+ }
967
+ } catch (fs::filesystem_error &ex) {
968
+ error (" %s: Exception occurred: %s. Failure occurred during attempt to load blocks from original "
969
+ " block data file(s)." , __func__, ex.what ());
970
+
971
+ successful = false ;
972
+ }
973
+
974
+ if (successful) {
975
+ try {
976
+ fs::path cleanup_path;
977
+
978
+ if (!GetActualCleanupPath (cleanup_path)) return false ;
979
+
980
+ for (const auto & iter : block_data_files) {
981
+ if (!fs::remove (iter.first )) {
982
+ LogPrintf (" WARN: %s: Reindexing of the blockchain was successful; however, one or more of "
983
+ " the original block data files (%s) was not able to be deleted. You "
984
+ " will have to delete this file manually." , __func__, iter.first .filename ().string ());
985
+ }
986
+ }
987
+ }
988
+ catch (fs::filesystem_error &ex) {
989
+ LogPrintf (" WARN: %s: Exception occurred: %s. This error occurred while attempting to delete the original block "
990
+ " data files (blk*.dat.orig). You will have to delete these manually." , __func__, ex.what ());
991
+ }
992
+ } else {
993
+ error (" %s: A failure occurred during the reindexing of the block data files. The blockchain state is invalid and "
994
+ " you should restart the wallet with the -resetblockchaindata option to clear out the blockchain database "
995
+ " and re-sync the blockchain from the network." , __func__);
996
+
997
+ DownloadStatus.SetCleanupBlockchainDataFailed (true );
998
+
999
+ return false ;
1000
+ }
1001
+
1002
+ LogPrintf (" INFO: %s: Reindex of the blockchain data was successful." , __func__);
1003
+
1004
+ return true ;
1005
+ }
1006
+
885
1007
std::string Upgrade::ResetBlockchainMessages (ResetBlockchainMsg _msg)
886
1008
{
887
1009
std::stringstream stream;
0 commit comments