Skip to content

Commit 0cdddeb

Browse files
committed
kernel: Move block tree db open to BlockManager constructor
Make the block db open RAII style by calling it in the BlockManager constructor. Before this change the block tree db was needlessly re-opened during startup when loading a completed snapshot. Improve this by letting the block manager open it on construction. This also simplifies the test code a bit. The change was initially motivated to make it easier for users of the kernel library to instantiate a BlockManager that may be used to read data from disk without loading the block index into a cache.
1 parent 7fbb1bc commit 0cdddeb

File tree

5 files changed

+23
-28
lines changed

5 files changed

+23
-28
lines changed

src/init.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -1215,12 +1215,21 @@ static ChainstateLoadResult InitAndLoadChainstate(
12151215
},
12161216
};
12171217
Assert(ApplyArgsManOptions(args, blockman_opts)); // no error can happen, already checked in AppInitParameterInteraction
1218+
1219+
// Creating the chainstate manager internally creates a BlockManager, opens
1220+
// the blocks tree db, and wipes existing block files in case of a reindex.
1221+
// The coinsdb is opened at a later point on LoadChainstate.
12181222
try {
12191223
node.chainman = std::make_unique<ChainstateManager>(*Assert(node.shutdown_signal), chainman_opts, blockman_opts);
1224+
} catch (dbwrapper_error& e) {
1225+
LogError("%s", e.what());
1226+
return {ChainstateLoadStatus::FAILURE, _("Error opening block database")};
12201227
} catch (std::exception& e) {
12211228
return {ChainstateLoadStatus::FAILURE_FATAL, Untranslated(strprintf("Failed to initialize ChainstateManager: %s", e.what()))};
12221229
}
12231230
ChainstateManager& chainman = *node.chainman;
1231+
if (chainman.m_interrupt) return {ChainstateLoadStatus::INTERRUPTED, {}};
1232+
12241233
// This is defined and set here instead of inline in validation.h to avoid a hard
12251234
// dependency between validation and index/base, since the latter is not in
12261235
// libbitcoinkernel.

src/node/blockstorage.cpp

+14-1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include <util/translation.h>
3737
#include <validation.h>
3838

39+
#include <cstddef>
3940
#include <map>
4041
#include <ranges>
4142
#include <unordered_map>
@@ -1183,7 +1184,19 @@ BlockManager::BlockManager(const util::SignalInterrupt& interrupt, Options opts)
11831184
m_opts{std::move(opts)},
11841185
m_block_file_seq{FlatFileSeq{m_opts.blocks_dir, "blk", m_opts.fast_prune ? 0x4000 /* 16kB */ : BLOCKFILE_CHUNK_SIZE}},
11851186
m_undo_file_seq{FlatFileSeq{m_opts.blocks_dir, "rev", UNDOFILE_CHUNK_SIZE}},
1186-
m_interrupt{interrupt} {}
1187+
m_interrupt{interrupt}
1188+
{
1189+
m_block_tree_db = std::make_unique<BlockTreeDB>(m_opts.block_tree_db_params);
1190+
1191+
if (m_opts.block_tree_db_params.wipe_data) {
1192+
m_block_tree_db->WriteReindexing(true);
1193+
m_blockfiles_indexed = false;
1194+
// If we're reindexing in prune mode, wipe away unusable block files and all undo data files
1195+
if (m_prune_mode) {
1196+
CleanupBlockRevFiles();
1197+
}
1198+
}
1199+
}
11871200

11881201
class ImportingNow
11891202
{

src/node/blockstorage.h

-2
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,6 @@ class BlockManager
268268
using Options = kernel::BlockManagerOpts;
269269

270270
explicit BlockManager(const util::SignalInterrupt& interrupt, Options opts);
271-
auto MakeBlockTreeDb() { return std::make_unique<BlockTreeDB>(m_opts.block_tree_db_params); }
272-
auto OptsWipeBlockTreeDb() { return m_opts.block_tree_db_params.wipe_data; }
273271

274272
const util::SignalInterrupt& m_interrupt;
275273
std::atomic<bool> m_importing{false};

src/node/chainstate.cpp

-23
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,7 @@
2323
#include <validation.h>
2424

2525
#include <algorithm>
26-
#include <atomic>
2726
#include <cassert>
28-
#include <limits>
29-
#include <memory>
3027
#include <vector>
3128

3229
using kernel::CacheSizes;
@@ -38,26 +35,6 @@ static ChainstateLoadResult CompleteChainstateInitialization(
3835
ChainstateManager& chainman,
3936
const ChainstateLoadOptions& options) EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
4037
{
41-
auto& pblocktree{chainman.m_blockman.m_block_tree_db};
42-
// new BlockTreeDB tries to delete the existing file, which
43-
// fails if it's still open from the previous loop. Close it first:
44-
pblocktree.reset();
45-
try {
46-
pblocktree = chainman.m_blockman.MakeBlockTreeDb();
47-
} catch (dbwrapper_error& err) {
48-
LogError("%s\n", err.what());
49-
return {ChainstateLoadStatus::FAILURE, _("Error opening block database")};
50-
}
51-
52-
if (chainman.m_blockman.OptsWipeBlockTreeDb()) {
53-
pblocktree->WriteReindexing(true);
54-
chainman.m_blockman.m_blockfiles_indexed = false;
55-
//If we're reindexing in prune mode, wipe away unusable block files and all undo data files
56-
if (options.prune) {
57-
chainman.m_blockman.CleanupBlockRevFiles();
58-
}
59-
}
60-
6138
if (chainman.m_interrupt) return {ChainstateLoadStatus::INTERRUPTED, {}};
6239

6340
// LoadBlockIndex will load m_have_pruned if we've ever removed a

src/test/util/setup_common.cpp

-2
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,6 @@ ChainTestingSetup::ChainTestingSetup(const ChainType chainType, TestOpts opts)
257257
},
258258
};
259259
m_node.chainman = std::make_unique<ChainstateManager>(*Assert(m_node.shutdown_signal), chainman_opts, blockman_opts);
260-
LOCK(m_node.chainman->GetMutex());
261-
m_node.chainman->m_blockman.m_block_tree_db = m_node.chainman->m_blockman.MakeBlockTreeDb();
262260
};
263261
m_make_chainman();
264262
}

0 commit comments

Comments
 (0)