From cb3ad361d1f2a7972e3fd11ee34efb77b35f8009 Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Sat, 23 Oct 2021 00:05:02 -0400 Subject: [PATCH 01/13] DBWrapper: Add constructor using Options struct The non-Options constructor is kept (it now calls the Options version of the constructor) so that we can fix callsites one-by-one without breaking builds, it will be removed later in this patchset. --- src/Makefile.am | 1 + src/dbwrapper.cpp | 43 +++++++++++++++++++++++----------- src/dbwrapper.h | 15 ++++++------ src/kernel/dbwrapper_options.h | 29 +++++++++++++++++++++++ 4 files changed, 66 insertions(+), 22 deletions(-) create mode 100644 src/kernel/dbwrapper_options.h diff --git a/src/Makefile.am b/src/Makefile.am index 18c6c25b96eb3..67786d78976f6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -174,6 +174,7 @@ BITCOIN_CORE_H = \ kernel/checks.h \ kernel/coinstats.h \ kernel/context.h \ + kernel/dbwrapper_options.h \ kernel/mempool_limits.h \ kernel/mempool_options.h \ kernel/mempool_persist.h \ diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp index 4dbc83994163a..a7675603d73a7 100644 --- a/src/dbwrapper.cpp +++ b/src/dbwrapper.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -127,40 +128,54 @@ static leveldb::Options GetOptions(size_t nCacheSize) return options; } +// REVIEW-ONLY: This particular constructor will be removed by the end of +// the patchset. CDBWrapper::CDBWrapper(const fs::path& path, size_t nCacheSize, bool fMemory, bool fWipe, bool obfuscate) - : m_name{fs::PathToString(path.stem())} + : CDBWrapper{{ + .db_path = path, + .cache_size = nCacheSize, + .in_memory = fMemory, + .wipe_existing = fWipe, + .obfuscate_data = obfuscate, + }} {} + +CDBWrapper::CDBWrapper(const Options& opts) + : m_name{[&]() { + Assert(!opts.db_path.empty()); + return fs::PathToString(opts.db_path.stem()); + }()} { penv = nullptr; readoptions.verify_checksums = true; iteroptions.verify_checksums = true; iteroptions.fill_cache = false; syncoptions.sync = true; - options = GetOptions(nCacheSize); + options = GetOptions(opts.cache_size); options.create_if_missing = true; - if (fMemory) { + if (opts.in_memory) { penv = leveldb::NewMemEnv(leveldb::Env::Default()); options.env = penv; } else { - if (fWipe) { - LogPrintf("Wiping LevelDB in %s\n", fs::PathToString(path)); - leveldb::Status result = leveldb::DestroyDB(fs::PathToString(path), options); + if (opts.wipe_existing) { + LogPrintf("Wiping LevelDB in %s\n", fs::PathToString(opts.db_path)); + leveldb::Status result = leveldb::DestroyDB(fs::PathToString(opts.db_path), options); dbwrapper_private::HandleError(result); } - TryCreateDirectories(path); - LogPrintf("Opening LevelDB in %s\n", fs::PathToString(path)); + TryCreateDirectories(opts.db_path); + LogPrintf("Opening LevelDB in %s\n", fs::PathToString(opts.db_path)); } // PathToString() return value is safe to pass to leveldb open function, // because on POSIX leveldb passes the byte string directly to ::open(), and // on Windows it converts from UTF-8 to UTF-16 before calling ::CreateFileW // (see env_posix.cc and env_windows.cc). - leveldb::Status status = leveldb::DB::Open(options, fs::PathToString(path), &pdb); + leveldb::Status status = leveldb::DB::Open(options, fs::PathToString(opts.db_path), &pdb); dbwrapper_private::HandleError(status); LogPrintf("Opened LevelDB successfully\n"); if (gArgs.GetBoolArg("-forcecompactdb", false)) { - LogPrintf("Starting database compaction of %s\n", fs::PathToString(path)); + LogPrintf("Starting database compaction of %s\n", fs::PathToString(opts.db_path)); pdb->CompactRange(nullptr, nullptr); - LogPrintf("Finished database compaction of %s\n", fs::PathToString(path)); + LogPrintf("Finished database compaction of %s\n", fs::PathToString(opts.db_path)); } // The base-case obfuscation key, which is a noop. @@ -168,7 +183,7 @@ CDBWrapper::CDBWrapper(const fs::path& path, size_t nCacheSize, bool fMemory, bo bool key_exists = Read(OBFUSCATE_KEY_KEY, obfuscate_key); - if (!key_exists && obfuscate && IsEmpty()) { + if (!key_exists && opts.obfuscate_data && IsEmpty()) { // Initialize non-degenerate obfuscation if it won't upset // existing, non-obfuscated data. std::vector new_key = CreateObfuscateKey(); @@ -177,10 +192,10 @@ CDBWrapper::CDBWrapper(const fs::path& path, size_t nCacheSize, bool fMemory, bo Write(OBFUSCATE_KEY_KEY, new_key); obfuscate_key = new_key; - LogPrintf("Wrote new obfuscate key for %s: %s\n", fs::PathToString(path), HexStr(obfuscate_key)); + LogPrintf("Wrote new obfuscate key for %s: %s\n", fs::PathToString(opts.db_path), HexStr(obfuscate_key)); } - LogPrintf("Using obfuscation key for %s: %s\n", fs::PathToString(path), HexStr(obfuscate_key)); + LogPrintf("Using obfuscation key for %s: %s\n", fs::PathToString(opts.db_path), HexStr(obfuscate_key)); } CDBWrapper::~CDBWrapper() diff --git a/src/dbwrapper.h b/src/dbwrapper.h index 665eaa0e98673..d96df12abd391 100644 --- a/src/dbwrapper.h +++ b/src/dbwrapper.h @@ -5,6 +5,8 @@ #ifndef BITCOIN_DBWRAPPER_H #define BITCOIN_DBWRAPPER_H +#include + #include #include #include @@ -220,15 +222,12 @@ class CDBWrapper std::vector CreateObfuscateKey() const; public: - /** - * @param[in] path Location in the filesystem where leveldb data will be stored. - * @param[in] nCacheSize Configures various leveldb cache settings. - * @param[in] fMemory If true, use leveldb's memory environment. - * @param[in] fWipe If true, remove all existing data. - * @param[in] obfuscate If true, store data obfuscated via simple XOR. If false, XOR - * with a zero'd byte array. - */ + using Options = kernel::DBWrapperOpts; + + // REVIEW-ONLY: This particular constructor will be removed by the end of + // the patchset. CDBWrapper(const fs::path& path, size_t nCacheSize, bool fMemory = false, bool fWipe = false, bool obfuscate = false); + CDBWrapper(const Options& opts); ~CDBWrapper(); CDBWrapper(const CDBWrapper&) = delete; diff --git a/src/kernel/dbwrapper_options.h b/src/kernel/dbwrapper_options.h new file mode 100644 index 0000000000000..9753c5655c82f --- /dev/null +++ b/src/kernel/dbwrapper_options.h @@ -0,0 +1,29 @@ +// Copyright (c) 2022 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_KERNEL_DBWRAPPER_OPTIONS_H +#define BITCOIN_KERNEL_DBWRAPPER_OPTIONS_H + +#include + +#include + +namespace kernel { + +struct DBWrapperOpts { + //! Location in the filesystem where leveldb data will be stored. + fs::path db_path; + //! Configures various leveldb cache settings. + size_t cache_size; + //! If true, use leveldb's memory environment. + bool in_memory = false; + //! If true, remove all existing data. + bool wipe_existing = false; + //! If true, store data obfuscated via simple XOR. If false, XOR with a zero'd byte array. + bool obfuscate_data = false; +}; + +} // namespace kernel + +#endif // BITCOIN_KERNEL_DBWRAPPER_OPTIONS_H From e8c8d1d89ffa89e85e30ccb9506ac09407c01ce3 Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Sat, 23 Oct 2021 00:05:02 -0400 Subject: [PATCH 02/13] DBWrapper: Pass in -forcecompactdb via ::Options --- src/dbwrapper.cpp | 3 ++- src/kernel/dbwrapper_options.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp index a7675603d73a7..06aaea3d38c62 100644 --- a/src/dbwrapper.cpp +++ b/src/dbwrapper.cpp @@ -137,6 +137,7 @@ CDBWrapper::CDBWrapper(const fs::path& path, size_t nCacheSize, bool fMemory, bo .in_memory = fMemory, .wipe_existing = fWipe, .obfuscate_data = obfuscate, + .do_compact = gArgs.GetBoolArg("-forcecompactdb", false), }} {} CDBWrapper::CDBWrapper(const Options& opts) @@ -172,7 +173,7 @@ CDBWrapper::CDBWrapper(const Options& opts) dbwrapper_private::HandleError(status); LogPrintf("Opened LevelDB successfully\n"); - if (gArgs.GetBoolArg("-forcecompactdb", false)) { + if (opts.do_compact) { LogPrintf("Starting database compaction of %s\n", fs::PathToString(opts.db_path)); pdb->CompactRange(nullptr, nullptr); LogPrintf("Finished database compaction of %s\n", fs::PathToString(opts.db_path)); diff --git a/src/kernel/dbwrapper_options.h b/src/kernel/dbwrapper_options.h index 9753c5655c82f..10cbd5e7459f1 100644 --- a/src/kernel/dbwrapper_options.h +++ b/src/kernel/dbwrapper_options.h @@ -22,6 +22,7 @@ struct DBWrapperOpts { bool wipe_existing = false; //! If true, store data obfuscated via simple XOR. If false, XOR with a zero'd byte array. bool obfuscate_data = false; + bool do_compact = false; }; } // namespace kernel From 5d04d046b4550a3e3991d74ad27267e42fce6d30 Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Tue, 26 Jul 2022 14:58:17 -0400 Subject: [PATCH 03/13] BlockTreeDB: Add yet unused ::Options, ApplyArgsManOptions --- src/Makefile.am | 3 +++ src/kernel/txdb_options.h | 44 +++++++++++++++++++++++++++++++++++++++ src/node/txdb_args.cpp | 18 ++++++++++++++++ src/node/txdb_args.h | 20 ++++++++++++++++++ src/txdb.h | 4 ++++ 5 files changed, 89 insertions(+) create mode 100644 src/kernel/txdb_options.h create mode 100644 src/node/txdb_args.cpp create mode 100644 src/node/txdb_args.h diff --git a/src/Makefile.am b/src/Makefile.am index 67786d78976f6..a4c0654f26d55 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -178,6 +178,7 @@ BITCOIN_CORE_H = \ kernel/mempool_limits.h \ kernel/mempool_options.h \ kernel/mempool_persist.h \ + kernel/txdb_options.h \ kernel/validation_cache_sizes.h \ key.h \ key_io.h \ @@ -208,6 +209,7 @@ BITCOIN_CORE_H = \ node/minisketchwrapper.h \ node/psbt.h \ node/transaction.h \ + node/txdb_args.h \ node/utxo_snapshot.h \ node/validation_cache_args.h \ noui.h \ @@ -393,6 +395,7 @@ libbitcoin_node_a_SOURCES = \ node/minisketchwrapper.cpp \ node/psbt.cpp \ node/transaction.cpp \ + node/txdb_args.cpp \ node/validation_cache_args.cpp \ noui.cpp \ policy/fees.cpp \ diff --git a/src/kernel/txdb_options.h b/src/kernel/txdb_options.h new file mode 100644 index 0000000000000..c9960db796ecd --- /dev/null +++ b/src/kernel/txdb_options.h @@ -0,0 +1,44 @@ +// Copyright (c) 2022 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_KERNEL_TXDB_OPTIONS_H +#define BITCOIN_KERNEL_TXDB_OPTIONS_H + +#include + +#include +#include + +class CChainParams; + +namespace kernel { + +/** + * An options struct for `CBlockTreeDB`, more ergonomically referred to as + * `CBlockTreeDB::Options` due to the using-declaration in + * `CBlockTreeDB`. + */ +struct BlockTreeDBOpts { + fs::path db_path; + size_t cache_size; + bool in_memory = false; + bool wipe_existing = false; + bool do_compact = false; + + DBWrapperOpts ToDBWrapperOptions() const + { + return DBWrapperOpts{ + .db_path = db_path, + .cache_size = cache_size, + .in_memory = in_memory, + .wipe_existing = wipe_existing, + .obfuscate_data = false, + .do_compact = do_compact, + }; + } +}; + +} // namespace kernel + +#endif // BITCOIN_KERNEL_TXDB_OPTIONS_H diff --git a/src/node/txdb_args.cpp b/src/node/txdb_args.cpp new file mode 100644 index 0000000000000..b1890f6d012e7 --- /dev/null +++ b/src/node/txdb_args.cpp @@ -0,0 +1,18 @@ +// Copyright (c) 2022 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include + +#include + +namespace node { + +void ApplyArgsManOptions(const ArgsManager& argsman, kernel::BlockTreeDBOpts& opts) +{ + opts.do_compact = argsman.GetBoolArg("-forcecompactdb", false); +} + +} // namespace node diff --git a/src/node/txdb_args.h b/src/node/txdb_args.h new file mode 100644 index 0000000000000..845314f7610c5 --- /dev/null +++ b/src/node/txdb_args.h @@ -0,0 +1,20 @@ +// Copyright (c) 2022 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_NODE_TXDB_ARGS_H +#define BITCOIN_NODE_TXDB_ARGS_H + +namespace kernel { +struct BlockTreeDBOpts; +} //namespace kernel + +class ArgsManager; + +namespace node { + +void ApplyArgsManOptions(const ArgsManager& argsman, kernel::BlockTreeDBOpts& opts); + +} // namespace node + +#endif // BITCOIN_NODE_TXDB_ARGS_H diff --git a/src/txdb.h b/src/txdb.h index a04596f7bbed3..a68d1b21aaa6e 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -6,6 +6,8 @@ #ifndef BITCOIN_TXDB_H #define BITCOIN_TXDB_H +#include + #include #include #include @@ -78,6 +80,8 @@ class CCoinsViewDB final : public CCoinsView class CBlockTreeDB : public CDBWrapper { public: + using Options = kernel::BlockTreeDBOpts; + explicit CBlockTreeDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); bool WriteBatchSync(const std::vector >& fileInfo, int nLastFile, const std::vector& blockinfo); From 09488528cbde58230bb405afe44b023f19a8be36 Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Wed, 3 Aug 2022 18:56:17 -0400 Subject: [PATCH 04/13] ChainManOpts: Add CBlockTreeDB::Options member Add an ApplyArgsManOptions function that currently just calls the ApplyArgsManOptions for CBlockTreeDB::Options. In a future commit in this patchset, this function will also call the ApplyArgsManOptions for CCoinsViewDB::Options. --- src/Makefile.am | 2 ++ src/kernel/chainstatemanager_opts.h | 3 +++ src/node/chainstatemanager_args.cpp | 20 ++++++++++++++++++++ src/node/chainstatemanager_args.h | 21 +++++++++++++++++++++ 4 files changed, 46 insertions(+) create mode 100644 src/node/chainstatemanager_args.cpp create mode 100644 src/node/chainstatemanager_args.h diff --git a/src/Makefile.am b/src/Makefile.am index a4c0654f26d55..fb9969b3c17f2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -198,6 +198,7 @@ BITCOIN_CORE_H = \ node/blockstorage.h \ node/caches.h \ node/chainstate.h \ + node/chainstatemanager_args.h \ node/coin.h \ node/connection_types.h \ node/context.h \ @@ -383,6 +384,7 @@ libbitcoin_node_a_SOURCES = \ node/blockstorage.cpp \ node/caches.cpp \ node/chainstate.cpp \ + node/chainstatemanager_args.cpp \ node/coin.cpp \ node/connection_types.cpp \ node/context.cpp \ diff --git a/src/kernel/chainstatemanager_opts.h b/src/kernel/chainstatemanager_opts.h index 510a1f9edcfae..4b599d88c74f1 100644 --- a/src/kernel/chainstatemanager_opts.h +++ b/src/kernel/chainstatemanager_opts.h @@ -5,6 +5,8 @@ #ifndef BITCOIN_KERNEL_CHAINSTATEMANAGER_OPTS_H #define BITCOIN_KERNEL_CHAINSTATEMANAGER_OPTS_H +#include + #include #include @@ -20,6 +22,7 @@ namespace kernel { struct ChainstateManagerOpts { const CChainParams& chainparams; const std::function adjusted_time_callback{nullptr}; + BlockTreeDBOpts block_tree_db_opts; }; } // namespace kernel diff --git a/src/node/chainstatemanager_args.cpp b/src/node/chainstatemanager_args.cpp new file mode 100644 index 0000000000000..6bdc11bc0dacf --- /dev/null +++ b/src/node/chainstatemanager_args.cpp @@ -0,0 +1,20 @@ +// Copyright (c) 2022 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include + +#include + +using kernel::ChainstateManagerOpts; + +namespace node { + +void ApplyArgsManOptions(const ArgsManager& argsman, ChainstateManagerOpts& chainman_opts) +{ + ApplyArgsManOptions(argsman, chainman_opts.block_tree_db_opts); +} + +} // namespace node diff --git a/src/node/chainstatemanager_args.h b/src/node/chainstatemanager_args.h new file mode 100644 index 0000000000000..dd63a2bd00837 --- /dev/null +++ b/src/node/chainstatemanager_args.h @@ -0,0 +1,21 @@ +// Copyright (c) 2022 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_NODE_CHAINSTATEMANAGER_ARGS_H +#define BITCOIN_NODE_CHAINSTATEMANAGER_ARGS_H + +class ArgsManager; +namespace kernel { +struct ChainstateManagerOpts; +}; + +namespace node { +/** + * Overlay the options set in \p argsman on top of corresponding members in \p chainman_opts. + */ +void ApplyArgsManOptions(const ArgsManager& argsman, kernel::ChainstateManagerOpts& chainman_opts); +} // namespace node + + +#endif // BITCOIN_NODE_CHAINSTATEMANAGER_ARGS_H From 422ee31897d14793efc0272ae75034a8528aad13 Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Tue, 26 Jul 2022 14:15:51 -0400 Subject: [PATCH 05/13] BlockTreeDB: Construct with {Chain,Block}Manager ctor Add a CBlockTreeDB::Options member to ChainstateManager::Options, and pass it down from ChainstateManager's ctor to BlockManager's ctor to CBlockTreeDB's new ctor that takes only a CBlockTreeDB::Options. This removes the need to reach into ChainstateManager -> BlockManager -> CBlockTreeDB right after you initialize the ChainstateManager, which was ugly. See node/chainstate.cpp and test/util/setup_common.cpp diffs. Notes: 1. In init.cpp, we needed to move the ChainstateManager initialization into the catch_exceptions block, otherwise exceptions thrown by the CBlockTreeDB ctor previously caught because they were in LoadChainstate would no longer be caught. 2. We also needed to add a data dir member to ChainstateManager::Options so that we can determine the default db_path for CBlockTreeDB if none is specified (See validation.h hunk). It does seem to make sense that ChainstateManager would know about what its data dir is anyway. --- src/bitcoin-chainstate.cpp | 13 +++++++++---- src/init.cpp | 24 ++++++++++++++++++------ src/kernel/chainstatemanager_opts.h | 1 + src/node/blockstorage.cpp | 3 +++ src/node/blockstorage.h | 2 ++ src/node/chainstate.cpp | 4 ---- src/node/chainstate.h | 1 - src/test/util/setup_common.cpp | 12 +++++++++--- src/txdb.cpp | 5 +++-- src/txdb.h | 2 +- src/validation.h | 13 ++++++++++++- 11 files changed, 58 insertions(+), 22 deletions(-) diff --git a/src/bitcoin-chainstate.cpp b/src/bitcoin-chainstate.cpp index fc3f91d4924fd..6bfd42a1f70a9 100644 --- a/src/bitcoin-chainstate.cpp +++ b/src/bitcoin-chainstate.cpp @@ -80,16 +80,21 @@ int main(int argc, char* argv[]) // SETUP: Chainstate + node::CacheSizes cache_sizes; + cache_sizes.block_tree_db = 2 << 20; + cache_sizes.coins_db = 2 << 22; + cache_sizes.coins = (450 << 20) - (2 << 20) - (2 << 22); + const ChainstateManager::Options chainman_opts{ .chainparams = chainparams, .adjusted_time_callback = static_cast(GetTime), + .block_tree_db_opts = { + .cache_size = static_cast(cache_sizes.block_tree_db), + }, + .data_dir = abs_datadir, }; ChainstateManager chainman{chainman_opts}; - node::CacheSizes cache_sizes; - cache_sizes.block_tree_db = 2 << 20; - cache_sizes.coins_db = 2 << 22; - cache_sizes.coins = (450 << 20) - (2 << 20) - (2 << 22); node::ChainstateLoadOptions options; options.check_interrupt = [] { return false; }; auto [status, error] = node::LoadChainstate(chainman, cache_sizes, options); diff --git a/src/init.cpp b/src/init.cpp index 4606b77e9ffbf..badd91ffbd921 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -40,11 +40,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -117,8 +119,8 @@ using node::DEFAULT_PRINTPRIORITY; using node::DEFAULT_STOPAFTERBLOCKIMPORT; using node::LoadChainstate; using node::MempoolPath; -using node::ShouldPersistMempool; using node::NodeContext; +using node::ShouldPersistMempool; using node::ThreadImport; using node::VerifyLoadedChainstate; using node::fPruneMode; @@ -1400,16 +1402,22 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) for (bool fLoaded = false; !fLoaded && !ShutdownRequested();) { node.mempool = std::make_unique(mempool_opts); - const ChainstateManager::Options chainman_opts{ + const bool do_reindex = fReindex; + + ChainstateManager::Options chainman_opts{ .chainparams = chainparams, .adjusted_time_callback = GetAdjustedTime, + .block_tree_db_opts = { + .cache_size = static_cast(cache_sizes.block_tree_db), + .wipe_existing = do_reindex, + }, + .data_dir = gArgs.GetDataDirNet(), }; - node.chainman = std::make_unique(chainman_opts); - ChainstateManager& chainman = *node.chainman; + ApplyArgsManOptions(args, chainman_opts); node::ChainstateLoadOptions options; options.mempool = Assert(node.mempool.get()); - options.reindex = node::fReindex; + options.reindex = do_reindex; options.reindex_chainstate = fReindexChainState; options.prune = node::fPruneMode; options.check_blocks = args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS); @@ -1431,8 +1439,12 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) return std::make_tuple(node::ChainstateLoadStatus::FAILURE, _("Error opening block database")); } }; - auto [status, error] = catch_exceptions([&]{ return LoadChainstate(chainman, cache_sizes, options); }); + auto [status, error] = catch_exceptions([&] { + node.chainman = std::make_unique(chainman_opts); + return LoadChainstate(*Assert(node.chainman), cache_sizes, options); + }); if (status == node::ChainstateLoadStatus::SUCCESS) { + ChainstateManager& chainman = *Assert(node.chainman); uiInterface.InitMessage(_("Verifying blocks…").translated); if (chainman.m_blockman.m_have_pruned && options.check_blocks > MIN_BLOCKS_TO_KEEP) { LogPrintfCategory(BCLog::PRUNE, "pruned datadir may not have more than %d blocks; only checking available blocks\n", diff --git a/src/kernel/chainstatemanager_opts.h b/src/kernel/chainstatemanager_opts.h index 4b599d88c74f1..b95c08468cc8a 100644 --- a/src/kernel/chainstatemanager_opts.h +++ b/src/kernel/chainstatemanager_opts.h @@ -23,6 +23,7 @@ struct ChainstateManagerOpts { const CChainParams& chainparams; const std::function adjusted_time_callback{nullptr}; BlockTreeDBOpts block_tree_db_opts; + const fs::path& data_dir; }; } // namespace kernel diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp index 601d0bdf58e0e..6486554f29c6a 100644 --- a/src/node/blockstorage.cpp +++ b/src/node/blockstorage.cpp @@ -58,6 +58,9 @@ static FILE* OpenUndoFile(const FlatFilePos& pos, bool fReadOnly = false); static FlatFileSeq BlockFileSeq(); static FlatFileSeq UndoFileSeq(); +BlockManager::BlockManager(const CBlockTreeDB::Options& block_tree_db_opts) + : m_block_tree_db{new CBlockTreeDB{block_tree_db_opts}} {} + std::vector BlockManager::GetAllBlockIndices() { AssertLockHeld(cs_main); diff --git a/src/node/blockstorage.h b/src/node/blockstorage.h index 9b76371aaec12..f1a4153cd98e2 100644 --- a/src/node/blockstorage.h +++ b/src/node/blockstorage.h @@ -140,6 +140,8 @@ class BlockManager std::unordered_map m_prune_locks GUARDED_BY(::cs_main); public: + explicit BlockManager(const CBlockTreeDB::Options& block_tree_db_opts); + BlockMap m_block_index GUARDED_BY(cs_main); std::vector GetAllBlockIndices() EXCLUSIVE_LOCKS_REQUIRED(::cs_main); diff --git a/src/node/chainstate.cpp b/src/node/chainstate.cpp index ad9293f172731..7968d1b39d442 100644 --- a/src/node/chainstate.cpp +++ b/src/node/chainstate.cpp @@ -38,10 +38,6 @@ ChainstateLoadResult LoadChainstate(ChainstateManager& chainman, const CacheSize chainman.m_total_coinsdb_cache = cache_sizes.coins_db; auto& pblocktree{chainman.m_blockman.m_block_tree_db}; - // new CBlockTreeDB tries to delete the existing file, which - // fails if it's still open from the previous loop. Close it first: - pblocktree.reset(); - pblocktree.reset(new CBlockTreeDB(cache_sizes.block_tree_db, options.block_tree_db_in_memory, options.reindex)); if (options.reindex) { pblocktree->WriteReindexing(true); diff --git a/src/node/chainstate.h b/src/node/chainstate.h index 2289310ece8cc..b889835d01378 100644 --- a/src/node/chainstate.h +++ b/src/node/chainstate.h @@ -20,7 +20,6 @@ struct CacheSizes; struct ChainstateLoadOptions { CTxMemPool* mempool{nullptr}; - bool block_tree_db_in_memory{false}; bool coins_db_in_memory{false}; bool reindex{false}; bool reindex_chainstate{false}; diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 30d26ecf798e2..11ac7a49007df 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -190,12 +191,18 @@ ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::ve m_cache_sizes = CalculateCacheSizes(m_args); - const ChainstateManager::Options chainman_opts{ + ChainstateManager::Options chainman_opts{ .chainparams = chainparams, .adjusted_time_callback = GetAdjustedTime, + .block_tree_db_opts = { + .cache_size = static_cast(m_cache_sizes.block_tree_db), + .in_memory = true, + }, + .data_dir = m_args.GetDataDirNet(), }; + ApplyArgsManOptions(m_args, chainman_opts); + m_node.chainman = std::make_unique(chainman_opts); - m_node.chainman->m_blockman.m_block_tree_db = std::make_unique(m_cache_sizes.block_tree_db, true); // Start script-checking threads. Set g_parallel_script_checks to true so they are used. constexpr int script_check_threads = 2; @@ -228,7 +235,6 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector #include +#include #include #include #include @@ -177,8 +178,8 @@ size_t CCoinsViewDB::EstimateSize() const return m_db->EstimateSize(DB_COIN, uint8_t(DB_COIN + 1)); } -CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CDBWrapper(gArgs.GetDataDirNet() / "blocks" / "index", nCacheSize, fMemory, fWipe) { -} +CBlockTreeDB::CBlockTreeDB(const Options& opts) + : CDBWrapper{opts.ToDBWrapperOptions()} {} bool CBlockTreeDB::ReadBlockFileInfo(int nFile, CBlockFileInfo &info) { return Read(std::make_pair(DB_BLOCK_FILES, nFile), info); diff --git a/src/txdb.h b/src/txdb.h index a68d1b21aaa6e..0029d08430f3e 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -82,7 +82,7 @@ class CBlockTreeDB : public CDBWrapper public: using Options = kernel::BlockTreeDBOpts; - explicit CBlockTreeDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); + explicit CBlockTreeDB(const Options& opts); bool WriteBatchSync(const std::vector >& fileInfo, int nLastFile, const std::vector& blockinfo); bool ReadBlockFileInfo(int nFile, CBlockFileInfo &info); diff --git a/src/validation.h b/src/validation.h index 7c0294d1ad9f2..d5765b370a381 100644 --- a/src/validation.h +++ b/src/validation.h @@ -859,11 +859,22 @@ class ChainstateManager friend CChainState; public: + const fs::path& m_data_dir; + using Options = kernel::ChainstateManagerOpts; explicit ChainstateManager(const Options& opts) : m_chainparams{opts.chainparams}, - m_adjusted_time_callback{Assert(opts.adjusted_time_callback)} {}; + m_adjusted_time_callback{Assert(opts.adjusted_time_callback)}, + m_data_dir{opts.data_dir}, + m_blockman{ + [&data_dir = opts.data_dir](CBlockTreeDB::Options db_opts) { + if (db_opts.db_path.empty()) { + db_opts.db_path = data_dir / "blocks" / "index"; + } + return db_opts; + }(opts.block_tree_db_opts) + } {}; const CChainParams& GetParams() const { return m_chainparams; } const Consensus::Params& GetConsensus() const { return m_chainparams.GetConsensus(); } From a2703121f374ed9b49fc2a2728e52079e3a51ae6 Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Thu, 4 Aug 2022 16:41:06 -0400 Subject: [PATCH 06/13] Make BlockManager::m_block_tree_db a simple object Since each BlockManager's m_block_tree_db will now be initialized with the BlockManager ctor, we don't need it to be a unique_ptr any more. --- src/init.cpp | 2 +- src/node/blockstorage.cpp | 18 +++++++++--------- src/node/blockstorage.h | 2 +- src/node/chainstate.cpp | 2 +- src/validation.cpp | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index badd91ffbd921..055a010924c36 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1498,7 +1498,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) // ********************************************************* Step 8: start indexers if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) { - if (const auto error{WITH_LOCK(cs_main, return CheckLegacyTxindex(*Assert(chainman.m_blockman.m_block_tree_db)))}) { + if (const auto error{WITH_LOCK(cs_main, return CheckLegacyTxindex(chainman.m_blockman.m_block_tree_db))}) { return InitError(*error); } diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp index 6486554f29c6a..7a0f73a8f0156 100644 --- a/src/node/blockstorage.cpp +++ b/src/node/blockstorage.cpp @@ -59,7 +59,7 @@ static FlatFileSeq BlockFileSeq(); static FlatFileSeq UndoFileSeq(); BlockManager::BlockManager(const CBlockTreeDB::Options& block_tree_db_opts) - : m_block_tree_db{new CBlockTreeDB{block_tree_db_opts}} {} + : m_block_tree_db{block_tree_db_opts} {} std::vector BlockManager::GetAllBlockIndices() { @@ -259,7 +259,7 @@ CBlockIndex* BlockManager::InsertBlockIndex(const uint256& hash) bool BlockManager::LoadBlockIndex(const Consensus::Params& consensus_params) { - if (!m_block_tree_db->LoadBlockIndexGuts(consensus_params, [this](const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { return this->InsertBlockIndex(hash); })) { + if (!m_block_tree_db.LoadBlockIndexGuts(consensus_params, [this](const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { return this->InsertBlockIndex(hash); })) { return false; } @@ -316,7 +316,7 @@ bool BlockManager::WriteBlockIndexDB() vBlocks.push_back(*it); m_dirty_blockindex.erase(it++); } - if (!m_block_tree_db->WriteBatchSync(vFiles, m_last_blockfile, vBlocks)) { + if (!m_block_tree_db.WriteBatchSync(vFiles, m_last_blockfile, vBlocks)) { return false; } return true; @@ -329,16 +329,16 @@ bool BlockManager::LoadBlockIndexDB(const Consensus::Params& consensus_params) } // Load block file info - m_block_tree_db->ReadLastBlockFile(m_last_blockfile); + m_block_tree_db.ReadLastBlockFile(m_last_blockfile); m_blockfile_info.resize(m_last_blockfile + 1); LogPrintf("%s: last block file = %i\n", __func__, m_last_blockfile); for (int nFile = 0; nFile <= m_last_blockfile; nFile++) { - m_block_tree_db->ReadBlockFileInfo(nFile, m_blockfile_info[nFile]); + m_block_tree_db.ReadBlockFileInfo(nFile, m_blockfile_info[nFile]); } LogPrintf("%s: last block file info: %s\n", __func__, m_blockfile_info[m_last_blockfile].ToString()); for (int nFile = m_last_blockfile + 1; true; nFile++) { CBlockFileInfo info; - if (m_block_tree_db->ReadBlockFileInfo(nFile, info)) { + if (m_block_tree_db.ReadBlockFileInfo(nFile, info)) { m_blockfile_info.push_back(info); } else { break; @@ -361,14 +361,14 @@ bool BlockManager::LoadBlockIndexDB(const Consensus::Params& consensus_params) } // Check whether we have ever pruned block & undo files - m_block_tree_db->ReadFlag("prunedblockfiles", m_have_pruned); + m_block_tree_db.ReadFlag("prunedblockfiles", m_have_pruned); if (m_have_pruned) { LogPrintf("LoadBlockIndexDB(): Block files have previously been pruned\n"); } // Check whether we need to continue reindexing bool fReindexing = false; - m_block_tree_db->ReadReindexing(fReindexing); + m_block_tree_db.ReadReindexing(fReindexing); if (fReindexing) fReindex = true; return true; @@ -858,7 +858,7 @@ void ThreadImport(ChainstateManager& chainman, std::vector vImportFile } nFile++; } - WITH_LOCK(::cs_main, chainman.m_blockman.m_block_tree_db->WriteReindexing(false)); + WITH_LOCK(::cs_main, chainman.m_blockman.m_block_tree_db.WriteReindexing(false)); fReindex = false; LogPrintf("Reindexing finished\n"); // To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked): diff --git a/src/node/blockstorage.h b/src/node/blockstorage.h index f1a4153cd98e2..4d354ef1bb1f6 100644 --- a/src/node/blockstorage.h +++ b/src/node/blockstorage.h @@ -152,7 +152,7 @@ class BlockManager */ std::multimap m_blocks_unlinked; - std::unique_ptr m_block_tree_db GUARDED_BY(::cs_main); + CBlockTreeDB m_block_tree_db GUARDED_BY(::cs_main); bool WriteBlockIndexDB() EXCLUSIVE_LOCKS_REQUIRED(::cs_main); bool LoadBlockIndexDB(const Consensus::Params& consensus_params) EXCLUSIVE_LOCKS_REQUIRED(::cs_main); diff --git a/src/node/chainstate.cpp b/src/node/chainstate.cpp index 7968d1b39d442..7a463f08a59ec 100644 --- a/src/node/chainstate.cpp +++ b/src/node/chainstate.cpp @@ -40,7 +40,7 @@ ChainstateLoadResult LoadChainstate(ChainstateManager& chainman, const CacheSize auto& pblocktree{chainman.m_blockman.m_block_tree_db}; if (options.reindex) { - pblocktree->WriteReindexing(true); + pblocktree.WriteReindexing(true); //If we're reindexing in prune mode, wipe away unusable block files and all undo data files if (options.prune) { CleanupBlockRevFiles(); diff --git a/src/validation.cpp b/src/validation.cpp index d30333f71036e..e773514f03b45 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2377,7 +2377,7 @@ bool CChainState::FlushStateToDisk( if (!setFilesToPrune.empty()) { fFlushForPrune = true; if (!m_blockman.m_have_pruned) { - m_blockman.m_block_tree_db->WriteFlag("prunedblockfiles", true); + m_blockman.m_block_tree_db.WriteFlag("prunedblockfiles", true); m_blockman.m_have_pruned = true; } } From 055700f36dbd054e5bb25ef6d754bd93af9957c7 Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Tue, 19 Jul 2022 13:56:50 -0400 Subject: [PATCH 07/13] CoinsViewDB: Add yet unused ::Options, ApplyArgsManOptions --- src/init.cpp | 1 + src/kernel/txdb_options.h | 31 +++++++++++++++++++++++++++++++ src/node/txdb_args.cpp | 7 +++++++ src/node/txdb_args.h | 2 ++ src/txdb.cpp | 2 ++ src/txdb.h | 4 ++-- 6 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 055a010924c36..3ed822e4bb2ca 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -110,6 +110,7 @@ using kernel::DumpMempool; using kernel::ValidationCacheSizes; +using kernel::nDefaultDbBatchSize; using node::ApplyArgsManOptions; using node::CacheSizes; diff --git a/src/kernel/txdb_options.h b/src/kernel/txdb_options.h index c9960db796ecd..0ea74534ea604 100644 --- a/src/kernel/txdb_options.h +++ b/src/kernel/txdb_options.h @@ -39,6 +39,37 @@ struct BlockTreeDBOpts { } }; +//! -dbbatchsize default (bytes) +static constexpr int64_t nDefaultDbBatchSize{16 << 20}; + +/** + * An options struct for `ChainstateManager`, more ergonomically referred to as + * `ChainstateManager::Options` due to the using-declaration in + * `ChainstateManager`. + */ +struct CoinsViewDBOpts { + fs::path db_path; + size_t cache_size; + bool in_memory = false; + bool wipe_existing = false; + bool do_compact = false; + size_t batch_write_size = nDefaultDbBatchSize; + int simulate_write_crash_ratio = 0; + + DBWrapperOpts ToDBWrapperOptions() const + { + return DBWrapperOpts{ + .db_path = db_path, + .cache_size = cache_size, + .in_memory = in_memory, + .wipe_existing = wipe_existing, + .obfuscate_data = true, + .do_compact = do_compact, + }; + } +}; + + } // namespace kernel #endif // BITCOIN_KERNEL_TXDB_OPTIONS_H diff --git a/src/node/txdb_args.cpp b/src/node/txdb_args.cpp index b1890f6d012e7..d9e98d4eb7d0d 100644 --- a/src/node/txdb_args.cpp +++ b/src/node/txdb_args.cpp @@ -15,4 +15,11 @@ void ApplyArgsManOptions(const ArgsManager& argsman, kernel::BlockTreeDBOpts& op opts.do_compact = argsman.GetBoolArg("-forcecompactdb", false); } +void ApplyArgsManOptions(const ArgsManager& argsman, kernel::CoinsViewDBOpts& coinsviewdb_opts) +{ + coinsviewdb_opts.do_compact = argsman.GetBoolArg("-forcecompactdb", coinsviewdb_opts.do_compact); + coinsviewdb_opts.batch_write_size = argsman.GetIntArg("-dbbatchsize", coinsviewdb_opts.batch_write_size); + coinsviewdb_opts.simulate_write_crash_ratio = argsman.GetIntArg("-dbcrashratio", coinsviewdb_opts.simulate_write_crash_ratio); +} + } // namespace node diff --git a/src/node/txdb_args.h b/src/node/txdb_args.h index 845314f7610c5..3cbbc981d4782 100644 --- a/src/node/txdb_args.h +++ b/src/node/txdb_args.h @@ -7,6 +7,7 @@ namespace kernel { struct BlockTreeDBOpts; +struct CoinsViewDBOpts; } //namespace kernel class ArgsManager; @@ -14,6 +15,7 @@ class ArgsManager; namespace node { void ApplyArgsManOptions(const ArgsManager& argsman, kernel::BlockTreeDBOpts& opts); +void ApplyArgsManOptions(const ArgsManager& argsman, kernel::CoinsViewDBOpts& coinsviewdb_opts); } // namespace node diff --git a/src/txdb.cpp b/src/txdb.cpp index d46b6cbbb3f2d..0c8a24df443b7 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -17,6 +17,8 @@ #include +using kernel::nDefaultDbBatchSize; + static constexpr uint8_t DB_COIN{'C'}; static constexpr uint8_t DB_BLOCK_FILES{'f'}; static constexpr uint8_t DB_BLOCK_INDEX{'b'}; diff --git a/src/txdb.h b/src/txdb.h index 0029d08430f3e..2ed7e9207729f 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -28,8 +28,6 @@ struct bilingual_str; //! -dbcache default (MiB) static const int64_t nDefaultDbCache = 450; -//! -dbbatchsize default (bytes) -static const int64_t nDefaultDbBatchSize = 16 << 20; //! max. -dbcache (MiB) static const int64_t nMaxDbCache = sizeof(void*) > 4 ? 16384 : 1024; //! min. -dbcache (MiB) @@ -51,6 +49,8 @@ extern RecursiveMutex cs_main; /** CCoinsView backed by the coin database (chainstate/) */ class CCoinsViewDB final : public CCoinsView { +public: + using Options = kernel::CoinsViewDBOpts; protected: std::unique_ptr m_db; fs::path m_ldb_path; From 0bec058a24bc4889693df86188c1261b8084b241 Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Tue, 26 Jul 2022 15:59:14 -0400 Subject: [PATCH 08/13] CoinsViewDB: Construct with ChainState{,Manager} ctor Add a CCoinsViewDB::Options member to ChainstateManager::Options, store it as a member in ChainstateManager's ctor, and pass it down to CChainState's ctor when CSM::{InitializeChainstate,ActivateSnapshot} is called. CChainState's ctor will then pass it down to CCoinsViews' new ctor that only takes a CBlockTreeDB::Options. This removes the need to call InitCoinsDB right after you construct your CChainState to have a working CChainState at all. In fact, CChainState::InitCoinsDB is entirely removed in this commit. --- src/bitcoin-chainstate.cpp | 5 ++ src/init.cpp | 5 ++ src/kernel/chainstatemanager_opts.h | 1 + src/node/chainstate.cpp | 6 --- src/node/chainstate.h | 1 - src/node/chainstatemanager_args.cpp | 1 + src/test/coins_tests.cpp | 12 ++++- src/test/fuzz/utxo_snapshot.cpp | 2 +- src/test/util/chainstate.h | 2 +- src/test/util/setup_common.cpp | 7 ++- src/test/util/setup_common.h | 2 +- src/test/validation_chainstate_tests.cpp | 2 - .../validation_chainstatemanager_tests.cpp | 8 --- src/txdb.cpp | 27 +++++----- src/txdb.h | 8 +-- src/validation.cpp | 49 ++++++++----------- src/validation.h | 23 +++------ 17 files changed, 79 insertions(+), 82 deletions(-) diff --git a/src/bitcoin-chainstate.cpp b/src/bitcoin-chainstate.cpp index 6bfd42a1f70a9..cb7cec989b58d 100644 --- a/src/bitcoin-chainstate.cpp +++ b/src/bitcoin-chainstate.cpp @@ -92,6 +92,11 @@ int main(int argc, char* argv[]) .cache_size = static_cast(cache_sizes.block_tree_db), }, .data_dir = abs_datadir, + .coins_view_db_opts = { + .cache_size = static_cast(cache_sizes.coins_db), + .in_memory = false, + .wipe_existing = false, + } }; ChainstateManager chainman{chainman_opts}; diff --git a/src/init.cpp b/src/init.cpp index 3ed822e4bb2ca..8d6c8266ec373 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1413,6 +1413,11 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) .wipe_existing = do_reindex, }, .data_dir = gArgs.GetDataDirNet(), + .coins_view_db_opts = { + .cache_size = static_cast(cache_sizes.coins_db), // FIXME + .in_memory = false, + .wipe_existing = do_reindex || fReindexChainState, + }, }; ApplyArgsManOptions(args, chainman_opts); diff --git a/src/kernel/chainstatemanager_opts.h b/src/kernel/chainstatemanager_opts.h index b95c08468cc8a..ef4f1ed6aad5a 100644 --- a/src/kernel/chainstatemanager_opts.h +++ b/src/kernel/chainstatemanager_opts.h @@ -24,6 +24,7 @@ struct ChainstateManagerOpts { const std::function adjusted_time_callback{nullptr}; BlockTreeDBOpts block_tree_db_opts; const fs::path& data_dir; + CoinsViewDBOpts coins_view_db_opts; }; } // namespace kernel diff --git a/src/node/chainstate.cpp b/src/node/chainstate.cpp index 7a463f08a59ec..38107865c2334 100644 --- a/src/node/chainstate.cpp +++ b/src/node/chainstate.cpp @@ -35,7 +35,6 @@ ChainstateLoadResult LoadChainstate(ChainstateManager& chainman, const CacheSize LOCK(cs_main); chainman.InitializeChainstate(options.mempool); chainman.m_total_coinstip_cache = cache_sizes.coins; - chainman.m_total_coinsdb_cache = cache_sizes.coins_db; auto& pblocktree{chainman.m_blockman.m_block_tree_db}; @@ -83,11 +82,6 @@ ChainstateLoadResult LoadChainstate(ChainstateManager& chainman, const CacheSize // block tree into BlockIndex()! for (CChainState* chainstate : chainman.GetAll()) { - chainstate->InitCoinsDB( - /*cache_size_bytes=*/cache_sizes.coins_db, - /*in_memory=*/options.coins_db_in_memory, - /*should_wipe=*/options.reindex || options.reindex_chainstate); - if (options.coins_error_cb) { chainstate->CoinsErrorCatcher().AddReadErrCallback(options.coins_error_cb); } diff --git a/src/node/chainstate.h b/src/node/chainstate.h index b889835d01378..380347d644973 100644 --- a/src/node/chainstate.h +++ b/src/node/chainstate.h @@ -20,7 +20,6 @@ struct CacheSizes; struct ChainstateLoadOptions { CTxMemPool* mempool{nullptr}; - bool coins_db_in_memory{false}; bool reindex{false}; bool reindex_chainstate{false}; bool prune{false}; diff --git a/src/node/chainstatemanager_args.cpp b/src/node/chainstatemanager_args.cpp index 6bdc11bc0dacf..a58b95dc3dbf3 100644 --- a/src/node/chainstatemanager_args.cpp +++ b/src/node/chainstatemanager_args.cpp @@ -15,6 +15,7 @@ namespace node { void ApplyArgsManOptions(const ArgsManager& argsman, ChainstateManagerOpts& chainman_opts) { ApplyArgsManOptions(argsman, chainman_opts.block_tree_db_opts); + ApplyArgsManOptions(argsman, chainman_opts.coins_view_db_opts); } } // namespace node diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index b333a9f72d16c..b00e37164f8cc 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -4,6 +4,7 @@ #include #include +#include #include