From 7fc893b7d5a64840efd5cb1e1e4196644ac1f766 Mon Sep 17 00:00:00 2001 From: furszy Date: Sun, 18 Apr 2021 21:32:28 -0300 Subject: [PATCH 01/13] [Test] BasicTestingSetup constructor receiving the network param. --- src/test/test_pivx.cpp | 11 +++++------ src/test/test_pivx.h | 5 +++-- src/test/validation_block_tests.cpp | 4 +--- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/test/test_pivx.cpp b/src/test/test_pivx.cpp index e15348900b950..19f87c8fa5e31 100644 --- a/src/test/test_pivx.cpp +++ b/src/test/test_pivx.cpp @@ -37,13 +37,13 @@ std::ostream& operator<<(std::ostream& os, const uint256& num) return os; } -BasicTestingSetup::BasicTestingSetup() +BasicTestingSetup::BasicTestingSetup(const std::string& chainName) { ECC_Start(); SetupEnvironment(); InitSignatureCache(); fCheckBlockIndex = true; - SelectParams(CBaseChainParams::MAIN); + SelectParams(chainName); evoDb.reset(new CEvoDB(1 << 20, true, true)); } BasicTestingSetup::~BasicTestingSetup() @@ -53,7 +53,7 @@ BasicTestingSetup::~BasicTestingSetup() evoDb.reset(); } -TestingSetup::TestingSetup() +TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(chainName) { ClearDatadirCache(); pathTemp = GetTempPath() / strprintf("test_pivx_%lu_%i", (unsigned long)GetTime(), (int)(InsecureRandRange(100000))); @@ -110,10 +110,9 @@ TestingSetup::~TestingSetup() fs::remove_all(pathTemp); } -TestChainSetup::TestChainSetup(int blockCount) +// Test chain only available on regtest +TestChainSetup::TestChainSetup(int blockCount) : TestingSetup(CBaseChainParams::REGTEST) { - SelectParams(CBaseChainParams::REGTEST); - // if blockCount is over PoS start, delay it to 100 blocks after. if (blockCount > Params().GetConsensus().vUpgrades[Consensus::UPGRADE_POS].nActivationHeight) { UpdateNetworkUpgradeParameters(Consensus::UPGRADE_POS, blockCount + 100); diff --git a/src/test/test_pivx.h b/src/test/test_pivx.h index 42f1b499cac88..cc4bf627d306e 100644 --- a/src/test/test_pivx.h +++ b/src/test/test_pivx.h @@ -34,7 +34,7 @@ static inline std::vector InsecureRandBytes(size_t len) { return * This just configures logging and chain parameters. */ struct BasicTestingSetup { - BasicTestingSetup(); + BasicTestingSetup(const std::string& chainName = CBaseChainParams::MAIN); ~BasicTestingSetup(); }; @@ -51,7 +51,7 @@ struct TestingSetup: public BasicTestingSetup { CScheduler scheduler; ECCVerifyHandle globalVerifyHandle; - TestingSetup(); + TestingSetup(const std::string& chainName = CBaseChainParams::MAIN); ~TestingSetup(); }; @@ -59,6 +59,7 @@ class CBlock; struct CMutableTransaction; class CScript; +// Test chain only available on regtest struct TestChainSetup : public TestingSetup { TestChainSetup(int blockCount); diff --git a/src/test/validation_block_tests.cpp b/src/test/validation_block_tests.cpp index 94445b0a6b9f6..9aae766b080de 100644 --- a/src/test/validation_block_tests.cpp +++ b/src/test/validation_block_tests.cpp @@ -15,9 +15,7 @@ #include "validationinterface.h" struct RegtestingSetup : public TestingSetup { - RegtestingSetup() : TestingSetup() { - SelectParams(CBaseChainParams::REGTEST); - } + RegtestingSetup() : TestingSetup(CBaseChainParams::REGTEST) {} }; BOOST_FIXTURE_TEST_SUITE(validation_block_tests, RegtestingSetup) From 5844452f64af4ba68aa9ab1ac800074a0e6d7636 Mon Sep 17 00:00:00 2001 From: furszy Date: Sun, 18 Apr 2021 21:40:33 -0300 Subject: [PATCH 02/13] Remove unneeded GetTempPath, only use temp directory in unit tests Based on btc#6702 btc#6701 --- src/test/test_pivx.cpp | 2 +- src/util.cpp | 5 ----- src/util.h | 1 - 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/test/test_pivx.cpp b/src/test/test_pivx.cpp index 19f87c8fa5e31..124d515542fe1 100644 --- a/src/test/test_pivx.cpp +++ b/src/test/test_pivx.cpp @@ -56,7 +56,7 @@ BasicTestingSetup::~BasicTestingSetup() TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(chainName) { ClearDatadirCache(); - pathTemp = GetTempPath() / strprintf("test_pivx_%lu_%i", (unsigned long)GetTime(), (int)(InsecureRandRange(100000))); + pathTemp = fs::temp_directory_path() / strprintf("test_pivx_%lu_%i", (unsigned long)GetTime(), (int)(InsecureRandRange(100000))); fs::create_directories(pathTemp); gArgs.ForceSetArg("-datadir", pathTemp.string()); diff --git a/src/util.cpp b/src/util.cpp index 444bf277247a9..d251da2b15a09 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -711,11 +711,6 @@ fs::path GetSpecialFolderPath(int nFolder, bool fCreate) } #endif -fs::path GetTempPath() -{ - return fs::temp_directory_path(); -} - void runCommand(std::string strCommand) { if (strCommand.empty()) return; diff --git a/src/util.h b/src/util.h index 41d96022d0bf8..c97809414e180 100644 --- a/src/util.h +++ b/src/util.h @@ -102,7 +102,6 @@ void CreatePidFile(const fs::path& path, pid_t pid); #ifdef WIN32 fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true); #endif -fs::path GetTempPath(); void runCommand(std::string strCommand); From a821b0ba058330314b31bf0dcd02858f558e9cad Mon Sep 17 00:00:00 2001 From: furszy Date: Tue, 20 Apr 2021 11:02:54 -0300 Subject: [PATCH 03/13] BugFix: Move TestingSetup::ECCVerifyHandle member to BasicTestingSetup. As the libsecp256k1 context was only initialized in the TestingSetup, we have been forced to use it when sometimes it is not necessary (TestingSetup is a complete setup that includes CConnman, scheduler, validation interface, etc). --- src/test/test_pivx.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/test_pivx.h b/src/test/test_pivx.h index cc4bf627d306e..67ed4d039377b 100644 --- a/src/test/test_pivx.h +++ b/src/test/test_pivx.h @@ -34,6 +34,8 @@ static inline std::vector InsecureRandBytes(size_t len) { return * This just configures logging and chain parameters. */ struct BasicTestingSetup { + ECCVerifyHandle globalVerifyHandle; + BasicTestingSetup(const std::string& chainName = CBaseChainParams::MAIN); ~BasicTestingSetup(); }; @@ -49,7 +51,6 @@ struct TestingSetup: public BasicTestingSetup { boost::thread_group threadGroup; CConnman* connman; CScheduler scheduler; - ECCVerifyHandle globalVerifyHandle; TestingSetup(const std::string& chainName = CBaseChainParams::MAIN); ~TestingSetup(); From 39b8127add94fa45d4c8744f59fef307da60c85e Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 20 Apr 2021 11:11:00 -0300 Subject: [PATCH 04/13] Allow to optional specify the directory for the blocks storage --- src/init.cpp | 11 ++++++++--- src/qt/pivx.cpp | 2 +- src/txdb.cpp | 2 +- src/util.cpp | 33 +++++++++++++++++++++++++++++++++ src/util.h | 1 + src/validation.cpp | 12 ++++++------ src/validation.h | 2 +- 7 files changed, 51 insertions(+), 12 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 1301b25ea1401..23f5a8aed02f5 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -422,6 +422,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-?", _("This help message")); strUsage += HelpMessageOpt("-version", _("Print version and exit")); strUsage += HelpMessageOpt("-alertnotify=", _("Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)")); + strUsage += HelpMessageOpt("-blocksdir=", _("Specify blocks directory (default: /blocks)")); strUsage += HelpMessageOpt("-blocknotify=", _("Execute command when the best block changes (%s in cmd is replaced by block hash)")); strUsage += HelpMessageOpt("-checkblocks=", strprintf(_("How many blocks to check at startup (default: %u, 0 = all)"), DEFAULT_CHECKBLOCKS)); strUsage += HelpMessageOpt("-conf=", strprintf(_("Specify configuration file (default: %s)"), PIVX_CONF_FILENAME)); @@ -1015,6 +1016,10 @@ bool AppInitParameterInteraction() { // ********************************************************* Step 2: parameter interactions + if (!fs::is_directory(GetBlocksDir(false))) { + return UIError(strprintf(_("Specified blocks directory \"%s\" does not exist.\n"), gArgs.GetArg("-blocksdir", "").c_str())); + } + // Make sure enough file descriptors are available // -bind and -whitebind can't be set when not listening @@ -1348,7 +1353,7 @@ bool AppInitMain() if (gArgs.GetBoolArg("-resync", false)) { uiInterface.InitMessage(_("Preparing for resync...")); // Delete the local blockchain folders to force a resync from scratch to get a consitent blockchain-state - fs::path blocksDir = GetDataDir() / "blocks"; + fs::path blocksDir = GetBlocksDir(); fs::path chainstateDir = GetDataDir() / "chainstate"; fs::path sporksDir = GetDataDir() / "sporks"; fs::path zerocoinDir = GetDataDir() / "zerocoin"; @@ -1539,7 +1544,7 @@ bool AppInitMain() fReindex = gArgs.GetBoolArg("-reindex", false); // Create blocks directory if it doesn't already exist - fs::create_directories(GetDataDir() / "blocks"); + fs::create_directories(GetBlocksDir()); // cache size calculations int64_t nTotalCache = (gArgs.GetArg("-dbcache", nDefaultDbCache) << 20); @@ -1770,7 +1775,7 @@ bool AppInitMain() #endif // ********************************************************* Step 9: import blocks - if (!CheckDiskSpace()) + if (!CheckDiskSpace() && !CheckDiskSpace(0, true)) return false; // Either install a handler to notify us when genesis activates, or set fHaveGenesis directly. diff --git a/src/qt/pivx.cpp b/src/qt/pivx.cpp index 0ad72348c9367..565bab191ae1a 100644 --- a/src/qt/pivx.cpp +++ b/src/qt/pivx.cpp @@ -600,7 +600,7 @@ int main(int argc, char* argv[]) if (!Intro::pickDataDirectory()) return 0; - /// 6. Determine availability of data directory and parse pivx.conf + /// 6. Determine availability of data and blocks directory and parse pivx.conf /// - Do not call GetDataDir(true) before this step finishes if (!fs::is_directory(GetDataDir(false))) { QMessageBox::critical(0, QObject::tr("PIVX Core"), diff --git a/src/txdb.cpp b/src/txdb.cpp index 1689a76770354..3ba7472f0cbe9 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -159,7 +159,7 @@ size_t CCoinsViewDB::EstimateSize() const return db.EstimateSize(DB_COIN, (char)(DB_COIN+1)); } -CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CDBWrapper(GetDataDir() / "blocks" / "index", nCacheSize, fMemory, fWipe) +CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CDBWrapper(GetBlocksDir() / "index", nCacheSize, fMemory, fWipe) { } diff --git a/src/util.cpp b/src/util.cpp index d251da2b15a09..d91fab60bac9c 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -318,6 +318,8 @@ fs::path GetDefaultDataDir() #endif } +static fs::path g_blocks_path_cached; +static fs::path g_blocks_path_cache_net_specific; static fs::path pathCached; static fs::path pathCachedNetSpecific; static fs::path zc_paramsPathCached; @@ -452,6 +454,35 @@ void initZKSNARKS() //std::cout << "### Sapling params initialized ###" << std::endl; } +const fs::path &GetBlocksDir(bool fNetSpecific) +{ + + LOCK(csPathCached); + + fs::path &path = fNetSpecific ? g_blocks_path_cache_net_specific : g_blocks_path_cached; + + // This can be called during exceptions by LogPrintf(), so we cache the + // value so we don't have to do memory allocations after that. + 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); + } + if (fNetSpecific) + path /= BaseParams().DataDir(); + + path /= "blocks"; + fs::create_directories(path); + return path; +} + const fs::path& GetDataDir(bool fNetSpecific) { LOCK(csPathCached); @@ -486,6 +517,8 @@ void ClearDatadirCache() pathCached = fs::path(); pathCachedNetSpecific = fs::path(); + g_blocks_path_cached = fs::path(); + g_blocks_path_cache_net_specific = fs::path(); } fs::path GetConfigFile() diff --git a/src/util.h b/src/util.h index c97809414e180..0261ca1ccaa53 100644 --- a/src/util.h +++ b/src/util.h @@ -87,6 +87,7 @@ void AllocateFileRange(FILE* file, unsigned int offset, unsigned int length); bool RenameOver(fs::path src, fs::path dest); bool TryCreateDirectory(const fs::path& p); fs::path GetDefaultDataDir(); +const fs::path &GetBlocksDir(bool fNetSpecific = true); const fs::path &GetDataDir(bool fNetSpecific = true); // Sapling network dir const fs::path &ZC_GetParamsDir(); diff --git a/src/validation.cpp b/src/validation.cpp index ead8f9f067bfc..c0c897dcd7956 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1852,7 +1852,7 @@ bool static FlushStateToDisk(CValidationState& state, FlushStateMode mode) // Write blocks and block index to disk. if (fDoFullFlush || fPeriodicWrite) { // Depend on nMinDiskSpace to ensure we can write block index - if (!CheckDiskSpace(0)) + if (!CheckDiskSpace(0, true)) return state.Error("out of disk space"); // First make sure all block and undo data is flushed to disk. FlushBlockFile(); @@ -2651,7 +2651,7 @@ bool FindBlockPos(CValidationState& state, CDiskBlockPos& pos, unsigned int nAdd unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE; unsigned int nNewChunks = (vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE; if (nNewChunks > nOldChunks) { - if (CheckDiskSpace(nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos)) { + if (CheckDiskSpace(nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos, true)) { FILE* file = OpenBlockFile(pos); if (file) { LogPrintf("Pre-allocating up to position 0x%x in blk%05u.dat\n", nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.nFile); @@ -2681,7 +2681,7 @@ bool FindUndoPos(CValidationState& state, int nFile, CDiskBlockPos& pos, unsigne unsigned int nOldChunks = (pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE; unsigned int nNewChunks = (nNewSize + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE; if (nNewChunks > nOldChunks) { - if (CheckDiskSpace(nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos)) { + if (CheckDiskSpace(nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos, true)) { FILE* file = OpenUndoFile(pos); if (file) { LogPrintf("Pre-allocating up to position 0x%x in rev%05u.dat\n", nNewChunks * UNDOFILE_CHUNK_SIZE, pos.nFile); @@ -3448,9 +3448,9 @@ bool TestBlockValidity(CValidationState& state, const CBlock& block, CBlockIndex return true; } -bool CheckDiskSpace(uint64_t nAdditionalBytes) +bool CheckDiskSpace(uint64_t nAdditionalBytes, bool blocks_dir) { - uint64_t nFreeBytesAvailable = fs::space(GetDataDir()).available; + uint64_t nFreeBytesAvailable = fs::space(blocks_dir ? GetBlocksDir() : GetDataDir()).available; // Check for nMinDiskSpace bytes (currently 50MB) if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes) @@ -3494,7 +3494,7 @@ FILE* OpenUndoFile(const CDiskBlockPos& pos, bool fReadOnly) fs::path GetBlockPosFilename(const CDiskBlockPos& pos, const char* prefix) { - return GetDataDir() / "blocks" / strprintf("%s%05u.dat", prefix, pos.nFile); + return GetBlocksDir() / strprintf("%s%05u.dat", prefix, pos.nFile); } CBlockIndex* InsertBlockIndex(uint256 hash) diff --git a/src/validation.h b/src/validation.h index cf31cefd805db..9b329e3e7cb0e 100644 --- a/src/validation.h +++ b/src/validation.h @@ -175,7 +175,7 @@ static const uint64_t nMinDiskSpace = 52428800; */ bool ProcessNewBlock(CValidationState& state, CNode* pfrom, const std::shared_ptr pblock, CDiskBlockPos* dbp, bool* fAccepted = nullptr); /** Check whether enough disk space is available for an incoming block */ -bool CheckDiskSpace(uint64_t nAdditionalBytes = 0); +bool CheckDiskSpace(uint64_t nAdditionalBytes = 0, bool blocks_dir = false); /** Open a block file (blk?????.dat) */ FILE* OpenBlockFile(const CDiskBlockPos& pos, bool fReadOnly = false); /** Open an undo file (rev?????.dat) */ From 3054076b5f028d5e9a343c3e8ae6b6f07a7dc263 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 9 Mar 2018 12:43:55 +0800 Subject: [PATCH 05/13] QA: Add -blocksdir test --- test/functional/feature_blocksdir.py | 34 ++++++++++++++++++++++++++++ test/functional/test_runner.py | 1 + 2 files changed, 35 insertions(+) create mode 100755 test/functional/feature_blocksdir.py diff --git a/test/functional/feature_blocksdir.py b/test/functional/feature_blocksdir.py new file mode 100755 index 0000000000000..34536fc35e9ff --- /dev/null +++ b/test/functional/feature_blocksdir.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +"""Test the blocksdir option. +""" + +from test_framework.test_framework import PivxTestFramework, initialize_datadir + +import shutil +import os + +class BlocksdirTest(PivxTestFramework): + def set_test_params(self): + self.setup_clean_chain = True + self.num_nodes = 1 + + def run_test(self): + self.stop_node(0) + node0path = os.path.join(self.options.tmpdir, "node0") + shutil.rmtree(node0path) + initialize_datadir(self.options.tmpdir, 0) + self.log.info("Starting with nonexistent blocksdir ...") + self.assert_start_raises_init_error(0, ["-blocksdir="+self.options.tmpdir+ "/blocksdir"], "Specified blocks director") + os.mkdir(self.options.tmpdir+ "/blocksdir") + self.log.info("Starting with existing blocksdir ...") + self.start_node(0, ["-blocksdir="+self.options.tmpdir+ "/blocksdir"]) + self.log.info("mining blocks..") + self.nodes[0].generate(10) + assert(os.path.isfile(self.options.tmpdir+ "/blocksdir/regtest/blocks/blk00000.dat")) + assert(os.path.isdir(self.options.tmpdir+ "/blocksdir/regtest/blocks/index")) + +if __name__ == '__main__': + BlocksdirTest().main() diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index 64bb0c1b5d3f4..6e01f48a1c897 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -114,6 +114,7 @@ 'rpc_blockchain.py', # ~ 50 sec 'wallet_disable.py', # ~ 50 sec 'mining_v5_upgrade.py', # ~ 48 sec + 'feature_blocksdir.py', 'p2p_mempool.py', # ~ 46 sec 'feature_help.py', # ~ 30 sec From a4ff899bb86d9517471717954619ee57265ec23c Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sun, 11 Mar 2018 12:42:02 +0800 Subject: [PATCH 06/13] -blocksdir: keep blockindex leveldb database in datadir --- src/txdb.cpp | 2 +- test/functional/feature_blocksdir.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/txdb.cpp b/src/txdb.cpp index 3ba7472f0cbe9..982c0ac80b65a 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -159,7 +159,7 @@ size_t CCoinsViewDB::EstimateSize() const return db.EstimateSize(DB_COIN, (char)(DB_COIN+1)); } -CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CDBWrapper(GetBlocksDir() / "index", nCacheSize, fMemory, fWipe) +CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CDBWrapper(gArgs.IsArgSet("-blocksdir") ? GetDataDir() / "blocks" / "index" : GetBlocksDir() / "index", nCacheSize, fMemory, fWipe) { } diff --git a/test/functional/feature_blocksdir.py b/test/functional/feature_blocksdir.py index 34536fc35e9ff..9d6350da0192a 100755 --- a/test/functional/feature_blocksdir.py +++ b/test/functional/feature_blocksdir.py @@ -27,8 +27,8 @@ def run_test(self): self.start_node(0, ["-blocksdir="+self.options.tmpdir+ "/blocksdir"]) self.log.info("mining blocks..") self.nodes[0].generate(10) - assert(os.path.isfile(self.options.tmpdir+ "/blocksdir/regtest/blocks/blk00000.dat")) - assert(os.path.isdir(self.options.tmpdir+ "/blocksdir/regtest/blocks/index")) + assert(os.path.isfile(os.path.join(self.options.tmpdir, "blocksdir", "regtest", "blocks", "blk00000.dat"))) + assert(os.path.isdir(os.path.join(self.options.tmpdir, "node0", "regtest", "blocks", "index"))) if __name__ == '__main__': BlocksdirTest().main() From 13a41194f8d6bc9dda04a7e99ccc5165e165af55 Mon Sep 17 00:00:00 2001 From: Daniel McNally Date: Tue, 2 Oct 2018 08:59:24 -0400 Subject: [PATCH 07/13] doc: Clarify -blocksdir usage This commit attempts to clarify and correct the `-blocksdir` argument description and default value. `-blocksdir` does not refer to the full path to the actual `blocks` directory, but rather the root/parent directory which contains the `blocks` directory. Accordingly, the default value is `` and not `/blocks`. It also attempts to clarify that only the `.dat` files containing block data are impacted by `-blocksdir`, not the index files. --- src/init.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index 23f5a8aed02f5..d994be8c52812 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -422,7 +422,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-?", _("This help message")); strUsage += HelpMessageOpt("-version", _("Print version and exit")); strUsage += HelpMessageOpt("-alertnotify=", _("Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)")); - strUsage += HelpMessageOpt("-blocksdir=", _("Specify blocks directory (default: /blocks)")); + strUsage += HelpMessageOpt("-blocksdir=", _("Specify directory to hold blocks subdirectory for *.dat files (default: )")); strUsage += HelpMessageOpt("-blocknotify=", _("Execute command when the best block changes (%s in cmd is replaced by block hash)")); strUsage += HelpMessageOpt("-checkblocks=", strprintf(_("How many blocks to check at startup (default: %u, 0 = all)"), DEFAULT_CHECKBLOCKS)); strUsage += HelpMessageOpt("-conf=", strprintf(_("Specify configuration file (default: %s)"), PIVX_CONF_FILENAME)); From ff0ae45892c511278246bd99eea73b9f72af2df3 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Tue, 20 Apr 2021 11:29:22 -0300 Subject: [PATCH 08/13] Make blockdir always net specific The blocks directory is net specific by definition. Also this prevents the side effect of calling GetBlocksDir(false) in the non-mainnet environment. --- src/init.cpp | 2 +- src/util.cpp | 9 +++------ src/util.h | 3 ++- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index d994be8c52812..61afa9e0c76a1 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1016,7 +1016,7 @@ bool AppInitParameterInteraction() { // ********************************************************* Step 2: parameter interactions - if (!fs::is_directory(GetBlocksDir(false))) { + if (!fs::is_directory(GetBlocksDir())) { return UIError(strprintf(_("Specified blocks directory \"%s\" does not exist.\n"), gArgs.GetArg("-blocksdir", "").c_str())); } diff --git a/src/util.cpp b/src/util.cpp index d91fab60bac9c..fd1c4bf53e41a 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -318,7 +318,6 @@ fs::path GetDefaultDataDir() #endif } -static fs::path g_blocks_path_cached; static fs::path g_blocks_path_cache_net_specific; static fs::path pathCached; static fs::path pathCachedNetSpecific; @@ -454,12 +453,12 @@ void initZKSNARKS() //std::cout << "### Sapling params initialized ###" << std::endl; } -const fs::path &GetBlocksDir(bool fNetSpecific) +const fs::path &GetBlocksDir() { LOCK(csPathCached); - fs::path &path = fNetSpecific ? g_blocks_path_cache_net_specific : g_blocks_path_cached; + fs::path &path = g_blocks_path_cache_net_specific; // This can be called during exceptions by LogPrintf(), so we cache the // value so we don't have to do memory allocations after that. @@ -475,9 +474,8 @@ const fs::path &GetBlocksDir(bool fNetSpecific) } else { path = GetDataDir(false); } - if (fNetSpecific) - path /= BaseParams().DataDir(); + path /= BaseParams().DataDir(); path /= "blocks"; fs::create_directories(path); return path; @@ -517,7 +515,6 @@ void ClearDatadirCache() pathCached = fs::path(); pathCachedNetSpecific = fs::path(); - g_blocks_path_cached = fs::path(); g_blocks_path_cache_net_specific = fs::path(); } diff --git a/src/util.h b/src/util.h index 0261ca1ccaa53..da4238113405a 100644 --- a/src/util.h +++ b/src/util.h @@ -87,7 +87,8 @@ void AllocateFileRange(FILE* file, unsigned int offset, unsigned int length); bool RenameOver(fs::path src, fs::path dest); bool TryCreateDirectory(const fs::path& p); fs::path GetDefaultDataDir(); -const fs::path &GetBlocksDir(bool fNetSpecific = true); +// The blocks directory is always net specific. +const fs::path &GetBlocksDir(); const fs::path &GetDataDir(bool fNetSpecific = true); // Sapling network dir const fs::path &ZC_GetParamsDir(); From e567003f5f4b9fe88b7216b9e94bbfe523835555 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Fri, 30 Nov 2018 16:32:23 +0200 Subject: [PATCH 09/13] Improve blocksdir functional test. A new node should not create an unused `blocks` directory in the root of the data directory when `-testnet` or `-regtest` is specified. --- test/functional/feature_blocksdir.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/functional/feature_blocksdir.py b/test/functional/feature_blocksdir.py index 9d6350da0192a..af056541b3e02 100755 --- a/test/functional/feature_blocksdir.py +++ b/test/functional/feature_blocksdir.py @@ -17,8 +17,9 @@ def set_test_params(self): def run_test(self): self.stop_node(0) - node0path = os.path.join(self.options.tmpdir, "node0") - shutil.rmtree(node0path) + assert os.path.isdir(os.path.join(self.nodes[0].datadir, "regtest", "blocks")) + assert not os.path.isdir(os.path.join(self.nodes[0].datadir, "blocks")) + shutil.rmtree(self.nodes[0].datadir) initialize_datadir(self.options.tmpdir, 0) self.log.info("Starting with nonexistent blocksdir ...") self.assert_start_raises_init_error(0, ["-blocksdir="+self.options.tmpdir+ "/blocksdir"], "Specified blocks director") From a571d24a55f412545a5675166158f0f2d90344f6 Mon Sep 17 00:00:00 2001 From: Ben Woosley Date: Mon, 7 Jan 2019 10:56:28 -0800 Subject: [PATCH 10/13] Fail if either disk space check fails Rather than both. Introduced in 386a6b62a8a1db9dd0f354cb95b7585f555c7e5d --- src/init.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index 61afa9e0c76a1..522625615ff4c 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1775,8 +1775,14 @@ bool AppInitMain() #endif // ********************************************************* Step 9: import blocks - if (!CheckDiskSpace() && !CheckDiskSpace(0, true)) + if (!CheckDiskSpace(/* additional_bytes */ 0, /* blocks_dir */ false)) { + UIError(strprintf(_("Error: Disk space is low for %s"), GetDataDir())); return false; + } + if (!CheckDiskSpace(/* additional_bytes */ 0, /* blocks_dir */ true)) { + UIError(strprintf(_("Error: Disk space is low for %s"), GetBlocksDir())); + return false; + } // Either install a handler to notify us when genesis activates, or set fHaveGenesis directly. // No locking, as this happens before any background thread is started. From 035d3c242a24a79d8936f5849b40f1cd097562c6 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sat, 5 Oct 2019 09:38:56 +0300 Subject: [PATCH 11/13] util: Simplify path argument for CBlockTreeDB ctor This commit does not change behavior as GetBlocksDir() with unset "-blocksdir" returns the same path. --- src/txdb.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/txdb.cpp b/src/txdb.cpp index 982c0ac80b65a..1689a76770354 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -159,7 +159,7 @@ size_t CCoinsViewDB::EstimateSize() const return db.EstimateSize(DB_COIN, (char)(DB_COIN+1)); } -CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CDBWrapper(gArgs.IsArgSet("-blocksdir") ? GetDataDir() / "blocks" / "index" : GetBlocksDir() / "index", nCacheSize, fMemory, fWipe) +CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CDBWrapper(GetDataDir() / "blocks" / "index", nCacheSize, fMemory, fWipe) { } From 50e66c286e1fb43d7e3ce473042f70521b25589d Mon Sep 17 00:00:00 2001 From: Marko Bencun Date: Wed, 22 Feb 2017 18:10:00 +0900 Subject: [PATCH 12/13] Turn TryCreateDirectory() into TryCreateDirectories() Use case: TryCreateDirectory(GetDataDir() / "blocks" / "index") would fail if the blocks directory was not explicitly created before. The line that did so was in a weird location and could be removed as a result. --- src/dbwrapper.cpp | 2 +- src/init.cpp | 3 --- src/qt/intro.cpp | 2 +- src/util.cpp | 12 ++++++------ src/util.h | 2 +- src/wallet/db.cpp | 2 +- 6 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp index bd39e140a7771..5ac82fb2dc5fa 100644 --- a/src/dbwrapper.cpp +++ b/src/dbwrapper.cpp @@ -72,7 +72,7 @@ CDBWrapper::CDBWrapper(const fs::path& path, size_t nCacheSize, bool fMemory, bo leveldb::Status result = leveldb::DestroyDB(path.string(), options); dbwrapper_private::HandleError(result); } - TryCreateDirectory(path); + TryCreateDirectories(path); LogPrintf("Opening LevelDB in %s\n", path.string()); } leveldb::Status status = leveldb::DB::Open(options, path.string(), &pdb); diff --git a/src/init.cpp b/src/init.cpp index 522625615ff4c..b93663635a549 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1543,9 +1543,6 @@ bool AppInitMain() fReindex = gArgs.GetBoolArg("-reindex", false); - // Create blocks directory if it doesn't already exist - fs::create_directories(GetBlocksDir()); - // cache size calculations int64_t nTotalCache = (gArgs.GetArg("-dbcache", nDefaultDbCache) << 20); nTotalCache = std::max(nTotalCache, nMinDbCache << 20); // total cache cannot be less than nMinDbCache diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index 1f91e295a126f..1ed9cf7985989 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -193,7 +193,7 @@ bool Intro::pickDataDirectory() } dataDir = intro.getDataDirectory(); try { - TryCreateDirectory(GUIUtil::qstringToBoostPath(dataDir)); + TryCreateDirectories(GUIUtil::qstringToBoostPath(dataDir)); break; } catch (const fs::filesystem_error& e) { QMessageBox::critical(0, tr("PIVX Core"), diff --git a/src/util.cpp b/src/util.cpp index fd1c4bf53e41a..e32eff957fa75 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -309,7 +309,7 @@ fs::path GetDefaultDataDir() #ifdef MAC_OSX // Mac pathRet /= "Library/Application Support"; - TryCreateDirectory(pathRet); + TryCreateDirectories(pathRet); return pathRet / "PIVX"; #else // Unix @@ -344,7 +344,7 @@ static fs::path ZC_GetBaseParamsDir() #ifdef MAC_OSX // Mac pathRet /= "Library/Application Support"; - TryCreateDirectory(pathRet); + TryCreateDirectories(pathRet); return pathRet / "PIVXParams"; #else // Unix @@ -597,20 +597,20 @@ bool RenameOver(fs::path src, fs::path dest) } /** - * Ignores exceptions thrown by Boost's create_directory if the requested directory exists. + * Ignores exceptions thrown by Boost's create_directories if the requested directory exists. * Specifically handles case where path p exists, but it wasn't possible for the user to * write to the parent directory. */ -bool TryCreateDirectory(const fs::path& p) +bool TryCreateDirectories(const fs::path& p) { try { - return fs::create_directory(p); + return fs::create_directories(p); } catch (const fs::filesystem_error&) { if (!fs::exists(p) || !fs::is_directory(p)) throw; } - // create_directory didn't create the directory, it had to have existed already + // create_directories didn't create the directory, it had to have existed already return false; } diff --git a/src/util.h b/src/util.h index da4238113405a..9b2db81113830 100644 --- a/src/util.h +++ b/src/util.h @@ -85,7 +85,7 @@ bool TruncateFile(FILE* file, unsigned int length); int RaiseFileDescriptorLimit(int nMinFD); void AllocateFileRange(FILE* file, unsigned int offset, unsigned int length); bool RenameOver(fs::path src, fs::path dest); -bool TryCreateDirectory(const fs::path& p); +bool TryCreateDirectories(const fs::path& p); fs::path GetDefaultDataDir(); // The blocks directory is always net specific. const fs::path &GetBlocksDir(); diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index 75a7789fd0edc..94b85583c1394 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -76,7 +76,7 @@ bool CDBEnv::Open(const fs::path& pathIn) strPath = pathIn.string(); fs::path pathLogDir = pathIn / "database"; - TryCreateDirectory(pathLogDir); + TryCreateDirectories(pathLogDir); fs::path pathErrorFile = pathIn / "db.log"; LogPrintf("CDBEnv::Open: LogDir=%s ErrorFile=%s\n", pathLogDir.string(), pathErrorFile.string()); From b0e0d554f6be1ec2fecbd1282d39a78eea7a9753 Mon Sep 17 00:00:00 2001 From: furszy Date: Thu, 29 Apr 2021 04:16:27 -0300 Subject: [PATCH 13/13] doc: add '-blocksdir' option to release-notes --- doc/release-notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index b86774f02aa9c..141b5829a5603 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -44,6 +44,9 @@ Notable Changes (Developers: add your notes here as part of your pull requests whenever possible) +#### Allow to optional specify the directory for the blocks storage + +A new init option flag '-blocksdir' will allow one to keep the blockfiles external from the data directory. #### Disable PoW mining RPC Commands