Skip to content

Commit 5921b86

Browse files
committed
init: Reset mempool and chainman via reconstruction
Fixes bitcoin#22964 Previously, we used UnloadBlockIndex() in order to reset node.mempool and node.chainman. However, that has proven to be fragile (see bitcoin#22964), and requires UnloadBlockIndex and its callees to be updated manually for each member that's introduced to the mempool and chainman classes. In this commit, we stop using the UnloadBlockIndex function and we simply reconstruct node.mempool and node.chainman. Since PeerManager needs a valid reference to both node.mempool and node.chainman, we also move PeerManager's construction via `::make` to after the chainstate activation sequence is complete. There are no more callers to UnloadBlockIndex after this commit, so it and its sole callees can be pruned.
1 parent 6e747e8 commit 5921b86

File tree

2 files changed

+16
-15
lines changed

2 files changed

+16
-15
lines changed

src/init.cpp

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,19 +1288,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
12881288
// as they would never get updated.
12891289
if (!ignores_incoming_txs) node.fee_estimator = std::make_unique<CBlockPolicyEstimator>();
12901290

1291-
assert(!node.mempool);
1292-
int check_ratio = std::min<int>(std::max<int>(args.GetIntArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000);
1293-
node.mempool = std::make_unique<CTxMemPool>(node.fee_estimator.get(), check_ratio);
1294-
1295-
assert(!node.chainman);
1296-
node.chainman = std::make_unique<ChainstateManager>();
1297-
ChainstateManager& chainman = *node.chainman;
1298-
1299-
assert(!node.peerman);
1300-
node.peerman = PeerManager::make(chainparams, *node.connman, *node.addrman, node.banman.get(),
1301-
chainman, *node.mempool, ignores_incoming_txs);
1302-
RegisterValidationInterface(node.peerman.get());
1303-
13041291
// sanitize comments per BIP-0014, format user agent and check total size
13051292
std::vector<std::string> uacomments;
13061293
for (const std::string& cmt : args.GetArgs("-uacomment")) {
@@ -1429,8 +1416,17 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
14291416
LogPrintf("* Using %.1f MiB for chain state database\n", cache_sizes.coins_db * (1.0 / 1024 / 1024));
14301417
LogPrintf("* Using %.1f MiB for in-memory UTXO set (plus up to %.1f MiB of unused mempool space)\n", cache_sizes.coins * (1.0 / 1024 / 1024), nMempoolSizeMax * (1.0 / 1024 / 1024));
14311418

1419+
assert(!node.mempool);
1420+
assert(!node.chainman);
1421+
int check_ratio = std::min<int>(std::max<int>(args.GetIntArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000);
1422+
14321423
bool fLoaded = false;
14331424
while (!fLoaded && !ShutdownRequested()) {
1425+
node.mempool = std::make_unique<CTxMemPool>(node.fee_estimator.get(), check_ratio);
1426+
1427+
node.chainman = std::make_unique<ChainstateManager>();
1428+
ChainstateManager& chainman = *node.chainman;
1429+
14341430
const bool fReset = fReindex;
14351431
bilingual_str strLoadError;
14361432

@@ -1562,6 +1558,13 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
15621558
return false;
15631559
}
15641560

1561+
ChainstateManager& chainman = *Assert(node.chainman);
1562+
1563+
assert(!node.peerman);
1564+
node.peerman = PeerManager::make(chainparams, *node.connman, *node.addrman, node.banman.get(),
1565+
chainman, *node.mempool, ignores_incoming_txs);
1566+
RegisterValidationInterface(node.peerman.get());
1567+
15651568
// ********************************************************* Step 8: start indexers
15661569
if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) {
15671570
if (const auto error{WITH_LOCK(cs_main, return CheckLegacyTxindex(*Assert(chainman.m_blockman.m_block_tree_db)))}) {

src/node/chainstate.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ std::optional<ChainstateLoadingError> LoadChainstate(bool fReset,
3232
chainman.m_total_coinstip_cache = nCoinCacheUsage;
3333
chainman.m_total_coinsdb_cache = nCoinDBCache;
3434

35-
UnloadBlockIndex(mempool, chainman);
36-
3735
auto& pblocktree{chainman.m_blockman.m_block_tree_db};
3836
// new CBlockTreeDB tries to delete the existing file, which
3937
// fails if it's still open from the previous loop. Close it first:

0 commit comments

Comments
 (0)