A GUI user may opt to retry once with do_reindex set if there is a failure during chainstate initialization. The function therefore has to support re-entry.
| 1317 | // A GUI user may opt to retry once with do_reindex set if there is a failure during chainstate initialization. |
| 1318 | // The function therefore has to support re-entry. |
| 1319 | static ChainstateLoadResult InitAndLoadChainstate( |
| 1320 | NodeContext& node, |
| 1321 | bool do_reindex, |
| 1322 | const bool do_reindex_chainstate, |
| 1323 | const kernel::CacheSizes& cache_sizes, |
| 1324 | const ArgsManager& args) |
| 1325 | { |
| 1326 | // This function may be called twice, so any dirty state must be reset. |
| 1327 | node.notifications->setChainstateLoaded(false); // Drop state, such as a cached tip block |
| 1328 | node.mempool.reset(); |
| 1329 | node.chainman.reset(); // Drop state, such as an initialized m_block_tree_db |
| 1330 | |
| 1331 | const CChainParams& chainparams = Params(); |
| 1332 | |
| 1333 | CTxMemPool::Options mempool_opts{ |
| 1334 | .check_ratio = chainparams.DefaultConsistencyChecks() ? 1 : 0, |
| 1335 | .signals = node.validation_signals.get(), |
| 1336 | }; |
| 1337 | Assert(ApplyArgsManOptions(args, chainparams, mempool_opts)); // no error can happen, already checked in AppInitParameterInteraction |
| 1338 | bilingual_str mempool_error; |
| 1339 | Assert(!node.mempool); // Was reset above |
| 1340 | node.mempool = std::make_unique<CTxMemPool>(mempool_opts, mempool_error); |
| 1341 | if (!mempool_error.empty()) { |
| 1342 | return {ChainstateLoadStatus::FAILURE_FATAL, mempool_error}; |
| 1343 | } |
| 1344 | auto mining_args{node::ReadMiningArgs(args)}; |
| 1345 | Assert(mining_args); // no error can happen, already checked in AppInitParameterInteraction |
| 1346 | node.mining_args = std::move(*mining_args); |
| 1347 | LogInfo("* Using %.1f MiB for in-memory UTXO set (plus up to %.1f MiB of unused mempool space)", |
| 1348 | cache_sizes.coins / double(1_MiB), |
| 1349 | mempool_opts.max_size_bytes / double(1_MiB)); |
| 1350 | ChainstateManager::Options chainman_opts{ |
| 1351 | .chainparams = chainparams, |
| 1352 | .datadir = args.GetDataDirNet(), |
| 1353 | .notifications = *node.notifications, |
| 1354 | .signals = node.validation_signals.get(), |
| 1355 | }; |
| 1356 | Assert(ApplyArgsManOptions(args, chainman_opts)); // no error can happen, already checked in AppInitParameterInteraction |
| 1357 | |
| 1358 | BlockManager::Options blockman_opts{ |
| 1359 | .chainparams = chainman_opts.chainparams, |
| 1360 | .blocks_dir = args.GetBlocksDirPath(), |
| 1361 | .notifications = chainman_opts.notifications, |
| 1362 | .block_tree_db_params = DBParams{ |
| 1363 | .path = args.GetDataDirNet() / "blocks" / "index", |
| 1364 | .cache_bytes = cache_sizes.block_tree_db, |
| 1365 | .wipe_data = do_reindex, |
| 1366 | }, |
| 1367 | }; |
| 1368 | Assert(ApplyArgsManOptions(args, blockman_opts)); // no error can happen, already checked in AppInitParameterInteraction |
| 1369 | |
| 1370 | // Creating the chainstate manager internally creates a BlockManager, opens |
| 1371 | // the blocks tree db, and wipes existing block files in case of a reindex. |
| 1372 | // The coinsdb is opened at a later point on LoadChainstate. |
| 1373 | Assert(!node.chainman); // Was reset above |
| 1374 | try { |
| 1375 | node.chainman = std::make_unique<ChainstateManager>(*Assert(node.shutdown_signal), chainman_opts, blockman_opts); |
| 1376 | } catch (dbwrapper_error& e) { |
no test coverage detected