mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-12 11:19:08 -05:00
kernel: Move block tree db open to block manager
This commit is done in preparation for the next commit. Here, the block tree options are moved to the blockmanager options and the block tree is instantiated through a helper method of the BlockManager, which is removed again in the next commit. Co-authored-by: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz>
This commit is contained in:
parent
57ba59c0cd
commit
7fbb1bc44b
12 changed files with 46 additions and 27 deletions
|
@ -106,6 +106,7 @@ int main(int argc, char* argv[])
|
||||||
};
|
};
|
||||||
auto notifications = std::make_unique<KernelNotifications>();
|
auto notifications = std::make_unique<KernelNotifications>();
|
||||||
|
|
||||||
|
kernel::CacheSizes cache_sizes{DEFAULT_KERNEL_CACHE};
|
||||||
|
|
||||||
// SETUP: Chainstate
|
// SETUP: Chainstate
|
||||||
auto chainparams = CChainParams::Main();
|
auto chainparams = CChainParams::Main();
|
||||||
|
@ -119,11 +120,14 @@ int main(int argc, char* argv[])
|
||||||
.chainparams = chainman_opts.chainparams,
|
.chainparams = chainman_opts.chainparams,
|
||||||
.blocks_dir = abs_datadir / "blocks",
|
.blocks_dir = abs_datadir / "blocks",
|
||||||
.notifications = chainman_opts.notifications,
|
.notifications = chainman_opts.notifications,
|
||||||
|
.block_tree_db_params = DBParams{
|
||||||
|
.path = abs_datadir / "blocks" / "index",
|
||||||
|
.cache_bytes = cache_sizes.block_tree_db,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
util::SignalInterrupt interrupt;
|
util::SignalInterrupt interrupt;
|
||||||
ChainstateManager chainman{interrupt, chainman_opts, blockman_opts};
|
ChainstateManager chainman{interrupt, chainman_opts, blockman_opts};
|
||||||
|
|
||||||
kernel::CacheSizes cache_sizes{DEFAULT_KERNEL_CACHE};
|
|
||||||
node::ChainstateLoadOptions options;
|
node::ChainstateLoadOptions options;
|
||||||
auto [status, error] = node::LoadChainstate(chainman, cache_sizes, options);
|
auto [status, error] = node::LoadChainstate(chainman, cache_sizes, options);
|
||||||
if (status != node::ChainstateLoadStatus::SUCCESS) {
|
if (status != node::ChainstateLoadStatus::SUCCESS) {
|
||||||
|
|
11
src/init.cpp
11
src/init.cpp
|
@ -1057,6 +1057,10 @@ bool AppInitParameterInteraction(const ArgsManager& args)
|
||||||
.chainparams = chainman_opts_dummy.chainparams,
|
.chainparams = chainman_opts_dummy.chainparams,
|
||||||
.blocks_dir = args.GetBlocksDirPath(),
|
.blocks_dir = args.GetBlocksDirPath(),
|
||||||
.notifications = chainman_opts_dummy.notifications,
|
.notifications = chainman_opts_dummy.notifications,
|
||||||
|
.block_tree_db_params = DBParams{
|
||||||
|
.path = args.GetDataDirNet() / "blocks" / "index",
|
||||||
|
.cache_bytes = 0,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
auto blockman_result{ApplyArgsManOptions(args, blockman_opts_dummy)};
|
auto blockman_result{ApplyArgsManOptions(args, blockman_opts_dummy)};
|
||||||
if (!blockman_result) {
|
if (!blockman_result) {
|
||||||
|
@ -1199,10 +1203,16 @@ static ChainstateLoadResult InitAndLoadChainstate(
|
||||||
.signals = node.validation_signals.get(),
|
.signals = node.validation_signals.get(),
|
||||||
};
|
};
|
||||||
Assert(ApplyArgsManOptions(args, chainman_opts)); // no error can happen, already checked in AppInitParameterInteraction
|
Assert(ApplyArgsManOptions(args, chainman_opts)); // no error can happen, already checked in AppInitParameterInteraction
|
||||||
|
|
||||||
BlockManager::Options blockman_opts{
|
BlockManager::Options blockman_opts{
|
||||||
.chainparams = chainman_opts.chainparams,
|
.chainparams = chainman_opts.chainparams,
|
||||||
.blocks_dir = args.GetBlocksDirPath(),
|
.blocks_dir = args.GetBlocksDirPath(),
|
||||||
.notifications = chainman_opts.notifications,
|
.notifications = chainman_opts.notifications,
|
||||||
|
.block_tree_db_params = DBParams{
|
||||||
|
.path = args.GetDataDirNet() / "blocks" / "index",
|
||||||
|
.cache_bytes = cache_sizes.block_tree_db,
|
||||||
|
.wipe_data = do_reindex,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
Assert(ApplyArgsManOptions(args, blockman_opts)); // no error can happen, already checked in AppInitParameterInteraction
|
Assert(ApplyArgsManOptions(args, blockman_opts)); // no error can happen, already checked in AppInitParameterInteraction
|
||||||
try {
|
try {
|
||||||
|
@ -1233,7 +1243,6 @@ static ChainstateLoadResult InitAndLoadChainstate(
|
||||||
};
|
};
|
||||||
node::ChainstateLoadOptions options;
|
node::ChainstateLoadOptions options;
|
||||||
options.mempool = Assert(node.mempool.get());
|
options.mempool = Assert(node.mempool.get());
|
||||||
options.wipe_block_tree_db = do_reindex;
|
|
||||||
options.wipe_chainstate_db = do_reindex || do_reindex_chainstate;
|
options.wipe_chainstate_db = do_reindex || do_reindex_chainstate;
|
||||||
options.prune = chainman.m_blockman.IsPruneMode();
|
options.prune = chainman.m_blockman.IsPruneMode();
|
||||||
options.check_blocks = args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS);
|
options.check_blocks = args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS);
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#ifndef BITCOIN_KERNEL_BLOCKMANAGER_OPTS_H
|
#ifndef BITCOIN_KERNEL_BLOCKMANAGER_OPTS_H
|
||||||
#define BITCOIN_KERNEL_BLOCKMANAGER_OPTS_H
|
#define BITCOIN_KERNEL_BLOCKMANAGER_OPTS_H
|
||||||
|
|
||||||
|
#include <dbwrapper.h>
|
||||||
#include <kernel/notifications_interface.h>
|
#include <kernel/notifications_interface.h>
|
||||||
#include <util/fs.h>
|
#include <util/fs.h>
|
||||||
|
|
||||||
|
@ -27,6 +28,7 @@ struct BlockManagerOpts {
|
||||||
bool fast_prune{false};
|
bool fast_prune{false};
|
||||||
const fs::path blocks_dir;
|
const fs::path blocks_dir;
|
||||||
Notifications& notifications;
|
Notifications& notifications;
|
||||||
|
DBParams block_tree_db_params;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
|
|
|
@ -42,7 +42,6 @@ struct ChainstateManagerOpts {
|
||||||
std::optional<uint256> assumed_valid_block{};
|
std::optional<uint256> assumed_valid_block{};
|
||||||
//! If the tip is older than this, the node is considered to be in initial block download.
|
//! If the tip is older than this, the node is considered to be in initial block download.
|
||||||
std::chrono::seconds max_tip_age{DEFAULT_MAX_TIP_AGE};
|
std::chrono::seconds max_tip_age{DEFAULT_MAX_TIP_AGE};
|
||||||
DBOptions block_tree_db{};
|
|
||||||
DBOptions coins_db{};
|
DBOptions coins_db{};
|
||||||
CoinsViewOptions coins_view{};
|
CoinsViewOptions coins_view{};
|
||||||
Notifications& notifications;
|
Notifications& notifications;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <common/args.h>
|
#include <common/args.h>
|
||||||
#include <node/blockstorage.h>
|
#include <node/blockstorage.h>
|
||||||
|
#include <node/database_args.h>
|
||||||
#include <tinyformat.h>
|
#include <tinyformat.h>
|
||||||
#include <util/result.h>
|
#include <util/result.h>
|
||||||
#include <util/translation.h>
|
#include <util/translation.h>
|
||||||
|
@ -34,6 +35,8 @@ util::Result<void> ApplyArgsManOptions(const ArgsManager& args, BlockManager::Op
|
||||||
|
|
||||||
if (auto value{args.GetBoolArg("-fastprune")}) opts.fast_prune = *value;
|
if (auto value{args.GetBoolArg("-fastprune")}) opts.fast_prune = *value;
|
||||||
|
|
||||||
|
ReadDatabaseArgs(args, opts.block_tree_db_params.options);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
} // namespace node
|
} // namespace node
|
||||||
|
|
|
@ -268,6 +268,8 @@ public:
|
||||||
using Options = kernel::BlockManagerOpts;
|
using Options = kernel::BlockManagerOpts;
|
||||||
|
|
||||||
explicit BlockManager(const util::SignalInterrupt& interrupt, Options opts);
|
explicit BlockManager(const util::SignalInterrupt& interrupt, Options opts);
|
||||||
|
auto MakeBlockTreeDb() { return std::make_unique<BlockTreeDB>(m_opts.block_tree_db_params); }
|
||||||
|
auto OptsWipeBlockTreeDb() { return m_opts.block_tree_db_params.wipe_data; }
|
||||||
|
|
||||||
const util::SignalInterrupt& m_interrupt;
|
const util::SignalInterrupt& m_interrupt;
|
||||||
std::atomic<bool> m_importing{false};
|
std::atomic<bool> m_importing{false};
|
||||||
|
|
|
@ -36,7 +36,6 @@ namespace node {
|
||||||
// to ChainstateManager::InitializeChainstate().
|
// to ChainstateManager::InitializeChainstate().
|
||||||
static ChainstateLoadResult CompleteChainstateInitialization(
|
static ChainstateLoadResult CompleteChainstateInitialization(
|
||||||
ChainstateManager& chainman,
|
ChainstateManager& chainman,
|
||||||
const CacheSizes& cache_sizes,
|
|
||||||
const ChainstateLoadOptions& options) EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
|
const ChainstateLoadOptions& options) EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
|
||||||
{
|
{
|
||||||
auto& pblocktree{chainman.m_blockman.m_block_tree_db};
|
auto& pblocktree{chainman.m_blockman.m_block_tree_db};
|
||||||
|
@ -44,18 +43,13 @@ static ChainstateLoadResult CompleteChainstateInitialization(
|
||||||
// fails if it's still open from the previous loop. Close it first:
|
// fails if it's still open from the previous loop. Close it first:
|
||||||
pblocktree.reset();
|
pblocktree.reset();
|
||||||
try {
|
try {
|
||||||
pblocktree = std::make_unique<BlockTreeDB>(DBParams{
|
pblocktree = chainman.m_blockman.MakeBlockTreeDb();
|
||||||
.path = chainman.m_options.datadir / "blocks" / "index",
|
|
||||||
.cache_bytes = cache_sizes.block_tree_db,
|
|
||||||
.memory_only = options.block_tree_db_in_memory,
|
|
||||||
.wipe_data = options.wipe_block_tree_db,
|
|
||||||
.options = chainman.m_options.block_tree_db});
|
|
||||||
} catch (dbwrapper_error& err) {
|
} catch (dbwrapper_error& err) {
|
||||||
LogError("%s\n", err.what());
|
LogError("%s\n", err.what());
|
||||||
return {ChainstateLoadStatus::FAILURE, _("Error opening block database")};
|
return {ChainstateLoadStatus::FAILURE, _("Error opening block database")};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.wipe_block_tree_db) {
|
if (chainman.m_blockman.OptsWipeBlockTreeDb()) {
|
||||||
pblocktree->WriteReindexing(true);
|
pblocktree->WriteReindexing(true);
|
||||||
chainman.m_blockman.m_blockfiles_indexed = false;
|
chainman.m_blockman.m_blockfiles_indexed = false;
|
||||||
//If we're reindexing in prune mode, wipe away unusable block files and all undo data files
|
//If we're reindexing in prune mode, wipe away unusable block files and all undo data files
|
||||||
|
@ -206,7 +200,7 @@ ChainstateLoadResult LoadChainstate(ChainstateManager& chainman, const CacheSize
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto [init_status, init_error] = CompleteChainstateInitialization(chainman, cache_sizes, options);
|
auto [init_status, init_error] = CompleteChainstateInitialization(chainman, options);
|
||||||
if (init_status != ChainstateLoadStatus::SUCCESS) {
|
if (init_status != ChainstateLoadStatus::SUCCESS) {
|
||||||
return {init_status, init_error};
|
return {init_status, init_error};
|
||||||
}
|
}
|
||||||
|
@ -242,7 +236,7 @@ ChainstateLoadResult LoadChainstate(ChainstateManager& chainman, const CacheSize
|
||||||
// for the fully validated chainstate.
|
// for the fully validated chainstate.
|
||||||
chainman.ActiveChainstate().ClearBlockIndexCandidates();
|
chainman.ActiveChainstate().ClearBlockIndexCandidates();
|
||||||
|
|
||||||
auto [init_status, init_error] = CompleteChainstateInitialization(chainman, cache_sizes, options);
|
auto [init_status, init_error] = CompleteChainstateInitialization(chainman, options);
|
||||||
if (init_status != ChainstateLoadStatus::SUCCESS) {
|
if (init_status != ChainstateLoadStatus::SUCCESS) {
|
||||||
return {init_status, init_error};
|
return {init_status, init_error};
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,12 +22,7 @@ namespace node {
|
||||||
|
|
||||||
struct ChainstateLoadOptions {
|
struct ChainstateLoadOptions {
|
||||||
CTxMemPool* mempool{nullptr};
|
CTxMemPool* mempool{nullptr};
|
||||||
bool block_tree_db_in_memory{false};
|
|
||||||
bool coins_db_in_memory{false};
|
bool coins_db_in_memory{false};
|
||||||
// Whether to wipe the block tree database when loading it. If set, this
|
|
||||||
// will also set a reindexing flag so any existing block data files will be
|
|
||||||
// scanned and added to the database.
|
|
||||||
bool wipe_block_tree_db{false};
|
|
||||||
// Whether to wipe the chainstate database when loading it. If set, this
|
// Whether to wipe the chainstate database when loading it. If set, this
|
||||||
// will cause the chainstate database to be rebuilt starting from genesis.
|
// will cause the chainstate database to be rebuilt starting from genesis.
|
||||||
bool wipe_chainstate_db{false};
|
bool wipe_chainstate_db{false};
|
||||||
|
|
|
@ -49,7 +49,6 @@ util::Result<void> ApplyArgsManOptions(const ArgsManager& args, ChainstateManage
|
||||||
|
|
||||||
if (auto value{args.GetIntArg("-maxtipage")}) opts.max_tip_age = std::chrono::seconds{*value};
|
if (auto value{args.GetIntArg("-maxtipage")}) opts.max_tip_age = std::chrono::seconds{*value};
|
||||||
|
|
||||||
ReadDatabaseArgs(args, opts.block_tree_db);
|
|
||||||
ReadDatabaseArgs(args, opts.coins_db);
|
ReadDatabaseArgs(args, opts.coins_db);
|
||||||
ReadCoinsViewArgs(args, opts.coins_view);
|
ReadCoinsViewArgs(args, opts.coins_view);
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,10 @@ BOOST_AUTO_TEST_CASE(blockmanager_find_block_pos)
|
||||||
.chainparams = *params,
|
.chainparams = *params,
|
||||||
.blocks_dir = m_args.GetBlocksDirPath(),
|
.blocks_dir = m_args.GetBlocksDirPath(),
|
||||||
.notifications = notifications,
|
.notifications = notifications,
|
||||||
|
.block_tree_db_params = DBParams{
|
||||||
|
.path = m_args.GetDataDirNet() / "blocks" / "index",
|
||||||
|
.cache_bytes = 0,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
BlockManager blockman{*Assert(m_node.shutdown_signal), blockman_opts};
|
BlockManager blockman{*Assert(m_node.shutdown_signal), blockman_opts};
|
||||||
// simulate adding a genesis block normally
|
// simulate adding a genesis block normally
|
||||||
|
@ -140,6 +144,10 @@ BOOST_AUTO_TEST_CASE(blockmanager_flush_block_file)
|
||||||
.chainparams = Params(),
|
.chainparams = Params(),
|
||||||
.blocks_dir = m_args.GetBlocksDirPath(),
|
.blocks_dir = m_args.GetBlocksDirPath(),
|
||||||
.notifications = notifications,
|
.notifications = notifications,
|
||||||
|
.block_tree_db_params = DBParams{
|
||||||
|
.path = m_args.GetDataDirNet() / "blocks" / "index",
|
||||||
|
.cache_bytes = 0,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
BlockManager blockman{*Assert(m_node.shutdown_signal), blockman_opts};
|
BlockManager blockman{*Assert(m_node.shutdown_signal), blockman_opts};
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,6 @@
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
using namespace util::hex_literals;
|
using namespace util::hex_literals;
|
||||||
using kernel::BlockTreeDB;
|
|
||||||
using node::ApplyArgsManOptions;
|
using node::ApplyArgsManOptions;
|
||||||
using node::BlockAssembler;
|
using node::BlockAssembler;
|
||||||
using node::BlockManager;
|
using node::BlockManager;
|
||||||
|
@ -250,14 +249,16 @@ ChainTestingSetup::ChainTestingSetup(const ChainType chainType, TestOpts opts)
|
||||||
.chainparams = chainman_opts.chainparams,
|
.chainparams = chainman_opts.chainparams,
|
||||||
.blocks_dir = m_args.GetBlocksDirPath(),
|
.blocks_dir = m_args.GetBlocksDirPath(),
|
||||||
.notifications = chainman_opts.notifications,
|
.notifications = chainman_opts.notifications,
|
||||||
|
.block_tree_db_params = DBParams{
|
||||||
|
.path = m_args.GetDataDirNet() / "blocks" / "index",
|
||||||
|
.cache_bytes = m_kernel_cache_sizes.block_tree_db,
|
||||||
|
.memory_only = opts.block_tree_db_in_memory,
|
||||||
|
.wipe_data = m_args.GetBoolArg("-reindex", false),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
m_node.chainman = std::make_unique<ChainstateManager>(*Assert(m_node.shutdown_signal), chainman_opts, blockman_opts);
|
m_node.chainman = std::make_unique<ChainstateManager>(*Assert(m_node.shutdown_signal), chainman_opts, blockman_opts);
|
||||||
LOCK(m_node.chainman->GetMutex());
|
LOCK(m_node.chainman->GetMutex());
|
||||||
m_node.chainman->m_blockman.m_block_tree_db = std::make_unique<BlockTreeDB>(DBParams{
|
m_node.chainman->m_blockman.m_block_tree_db = m_node.chainman->m_blockman.MakeBlockTreeDb();
|
||||||
.path = m_args.GetDataDirNet() / "blocks" / "index",
|
|
||||||
.cache_bytes = m_kernel_cache_sizes.block_tree_db,
|
|
||||||
.memory_only = true,
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
m_make_chainman();
|
m_make_chainman();
|
||||||
}
|
}
|
||||||
|
@ -283,9 +284,7 @@ void ChainTestingSetup::LoadVerifyActivateChainstate()
|
||||||
auto& chainman{*Assert(m_node.chainman)};
|
auto& chainman{*Assert(m_node.chainman)};
|
||||||
node::ChainstateLoadOptions options;
|
node::ChainstateLoadOptions options;
|
||||||
options.mempool = Assert(m_node.mempool.get());
|
options.mempool = Assert(m_node.mempool.get());
|
||||||
options.block_tree_db_in_memory = m_block_tree_db_in_memory;
|
|
||||||
options.coins_db_in_memory = m_coins_db_in_memory;
|
options.coins_db_in_memory = m_coins_db_in_memory;
|
||||||
options.wipe_block_tree_db = m_args.GetBoolArg("-reindex", false);
|
|
||||||
options.wipe_chainstate_db = m_args.GetBoolArg("-reindex", false) || m_args.GetBoolArg("-reindex-chainstate", false);
|
options.wipe_chainstate_db = m_args.GetBoolArg("-reindex", false) || m_args.GetBoolArg("-reindex-chainstate", false);
|
||||||
options.prune = chainman.m_blockman.IsPruneMode();
|
options.prune = chainman.m_blockman.IsPruneMode();
|
||||||
options.check_blocks = m_args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS);
|
options.check_blocks = m_args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS);
|
||||||
|
|
|
@ -393,6 +393,11 @@ struct SnapshotTestSetup : TestChain100Setup {
|
||||||
.chainparams = chainman_opts.chainparams,
|
.chainparams = chainman_opts.chainparams,
|
||||||
.blocks_dir = m_args.GetBlocksDirPath(),
|
.blocks_dir = m_args.GetBlocksDirPath(),
|
||||||
.notifications = chainman_opts.notifications,
|
.notifications = chainman_opts.notifications,
|
||||||
|
.block_tree_db_params = DBParams{
|
||||||
|
.path = chainman.m_options.datadir / "blocks" / "index",
|
||||||
|
.cache_bytes = m_kernel_cache_sizes.block_tree_db,
|
||||||
|
.memory_only = m_block_tree_db_in_memory,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
// For robustness, ensure the old manager is destroyed before creating a
|
// For robustness, ensure the old manager is destroyed before creating a
|
||||||
// new one.
|
// new one.
|
||||||
|
|
Loading…
Add table
Reference in a new issue