diff --git a/src/blockdb.cpp b/src/blockdb.cpp --- a/src/blockdb.cpp +++ b/src/blockdb.cpp @@ -10,11 +10,11 @@ extern RecursiveMutex cs_main; FlatFileSeq BlockFileSeq() { - return FlatFileSeq(GetBlocksDir(), "blk", BLOCKFILE_CHUNK_SIZE); + return FlatFileSeq(gArgs.GetBlocksDirPath(), "blk", BLOCKFILE_CHUNK_SIZE); } FlatFileSeq UndoFileSeq() { - return FlatFileSeq(GetBlocksDir(), "rev", UNDOFILE_CHUNK_SIZE); + return FlatFileSeq(gArgs.GetBlocksDirPath(), "rev", UNDOFILE_CHUNK_SIZE); } FILE *OpenBlockFile(const FlatFilePos &pos, bool fReadOnly) { diff --git a/src/init.cpp b/src/init.cpp --- a/src/init.cpp +++ b/src/init.cpp @@ -1372,8 +1372,7 @@ // ordered map keyed by block file index. LogPrintf("Removing unusable blk?????.dat and rev?????.dat files for " "-reindex with -prune\n"); - const auto directoryIterator = fs::directory_iterator{GetBlocksDir()}; - for (const auto &file : directoryIterator) { + for (const auto &file : fs::directory_iterator{gArgs.GetBlocksDirPath()}) { const auto fileName = file.path().filename().string(); if (fs::is_regular_file(file) && fileName.length() == 12 && fileName.substr(8, 4) == ".dat") { @@ -1798,7 +1797,7 @@ InitWarning(warnings); } - if (!fs::is_directory(GetBlocksDir())) { + if (!fs::is_directory(gArgs.GetBlocksDirPath())) { return InitError( strprintf(_("Specified blocks directory \"%s\" does not exist."), args.GetArg("-blocksdir", ""))); @@ -2895,9 +2894,9 @@ strprintf(_("Error: Disk space is low for %s"), GetDataDir())); return false; } - if (!CheckDiskSpace(GetBlocksDir())) { - InitError( - strprintf(_("Error: Disk space is low for %s"), GetBlocksDir())); + if (!CheckDiskSpace(gArgs.GetBlocksDirPath())) { + InitError(strprintf(_("Error: Disk space is low for %s"), + gArgs.GetBlocksDirPath())); return false; } diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -195,7 +195,7 @@ } QString ClientModel::blocksDir() const { - return GUIUtil::boostPathToQString(GetBlocksDir()); + return GUIUtil::boostPathToQString(gArgs.GetBlocksDirPath()); } void ClientModel::updateBanlist() { diff --git a/src/util/system.h b/src/util/system.h --- a/src/util/system.h +++ b/src/util/system.h @@ -82,8 +82,6 @@ bool TryCreateDirectories(const fs::path &p); fs::path GetDefaultDataDir(); -// The blocks directory is always net specific. -const fs::path &GetBlocksDir(); const fs::path &GetDataDir(bool fNetSpecific = true); // Return true if -datadir option points to a valid directory or is not // specified. @@ -182,6 +180,7 @@ std::map> m_available_args GUARDED_BY(cs_args); std::list m_config_sections GUARDED_BY(cs_args); + fs::path m_cached_blocks_path GUARDED_BY(cs_args); mutable fs::path m_cached_datadir_path GUARDED_BY(cs_args); mutable fs::path m_cached_network_datadir_path GUARDED_BY(cs_args); @@ -239,6 +238,13 @@ */ const std::list GetUnrecognizedSections() const; + /** + * Get blocks directory path + * + * @return Blocks path which is network specific + */ + const fs::path &GetBlocksDirPath(); + /** * Get data directory path * diff --git a/src/util/system.cpp b/src/util/system.cpp --- a/src/util/system.cpp +++ b/src/util/system.cpp @@ -401,6 +401,33 @@ return std::nullopt; } +const fs::path &ArgsManager::GetBlocksDirPath() { + LOCK(cs_args); + fs::path &path = m_cached_blocks_path; + + // Cache the path to avoid calling fs::create_directories on every call of + // this function + if (!path.empty()) { + return path; + } + + if (IsArgSet("-blocksdir")) { + path = fs::system_complete(GetArg("-blocksdir", "")); + if (!fs::is_directory(path)) { + path = ""; + return path; + } + } else { + path = GetDataDirPath(false); + } + + path /= BaseParams().DataDir(); + path /= "blocks"; + fs::create_directories(path); + path = StripRedundantLastElementsOfPath(path); + return path; +} + const fs::path &ArgsManager::GetDataDirPath(bool net_specific) const { LOCK(cs_args); fs::path &path = @@ -439,6 +466,7 @@ m_cached_datadir_path = fs::path(); m_cached_network_datadir_path = fs::path(); + m_cached_blocks_path = fs::path(); } std::vector ArgsManager::GetArgs(const std::string &strArg) const { @@ -797,36 +825,6 @@ #endif } -static fs::path g_blocks_path_cache_net_specific; -static RecursiveMutex csPathCached; - -const fs::path &GetBlocksDir() { - LOCK(csPathCached); - fs::path &path = g_blocks_path_cache_net_specific; - - // Cache the path to avoid calling fs::create_directories on every call of - // this function - if (!path.empty()) { - return path; - } - - if (gArgs.IsArgSet("-blocksdir")) { - path = fs::system_complete(gArgs.GetArg("-blocksdir", "")); - if (!fs::is_directory(path)) { - path = ""; - return path; - } - } else { - path = GetDataDir(false); - } - - path /= BaseParams().DataDir(); - path /= "blocks"; - fs::create_directories(path); - path = StripRedundantLastElementsOfPath(path); - return path; -} - const fs::path &GetDataDir(bool fNetSpecific) { return gArgs.GetDataDirPath(fNetSpecific); } @@ -838,7 +836,6 @@ void ClearDatadirCache() { gArgs.ClearDatadirPathCache(); - g_blocks_path_cache_net_specific = fs::path(); } fs::path GetConfigFile(const std::string &confPath) { diff --git a/src/validation.cpp b/src/validation.cpp --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2170,7 +2170,7 @@ // Write blocks and block index to disk. if (fDoFullFlush || fPeriodicWrite) { // Depend on nMinDiskSpace to ensure we can write block index - if (!CheckDiskSpace(GetBlocksDir())) { + if (!CheckDiskSpace(gArgs.GetBlocksDirPath())) { return AbortNode(state, "Disk space is too low!", _("Disk space is too low!")); }