| 1274 | }; |
| 1275 | |
| 1276 | void ImportBlocks(ChainstateManager& chainman, std::span<const fs::path> import_paths) |
| 1277 | { |
| 1278 | ImportingNow imp{chainman.m_blockman.m_importing}; |
| 1279 | |
| 1280 | // -reindex |
| 1281 | if (!chainman.m_blockman.m_blockfiles_indexed) { |
| 1282 | int total_files{0}; |
| 1283 | while (fs::exists(chainman.m_blockman.GetBlockPosFilename(FlatFilePos(total_files, 0)))) { |
| 1284 | total_files++; |
| 1285 | } |
| 1286 | |
| 1287 | // Map of disk positions for blocks with unknown parent (only used for reindex); |
| 1288 | // parent hash -> child disk position, multiple children can have the same parent. |
| 1289 | std::multimap<uint256, FlatFilePos> blocks_with_unknown_parent; |
| 1290 | |
| 1291 | for (int nFile{0}; nFile < total_files; ++nFile) { |
| 1292 | FlatFilePos pos(nFile, 0); |
| 1293 | AutoFile file{chainman.m_blockman.OpenBlockFile(pos, /*fReadOnly=*/true)}; |
| 1294 | if (file.IsNull()) { |
| 1295 | break; // This error is logged in OpenBlockFile |
| 1296 | } |
| 1297 | LogInfo("Reindexing block file blk%05u.dat (%d%% complete)...", (unsigned int)nFile, nFile * 100 / total_files); |
| 1298 | chainman.LoadExternalBlockFile(file, &pos, &blocks_with_unknown_parent); |
| 1299 | if (chainman.m_interrupt) { |
| 1300 | LogInfo("Interrupt requested. Exit reindexing."); |
| 1301 | return; |
| 1302 | } |
| 1303 | } |
| 1304 | WITH_LOCK(::cs_main, chainman.m_blockman.m_block_tree_db->WriteReindexing(false)); |
| 1305 | chainman.m_blockman.m_blockfiles_indexed = true; |
| 1306 | LogInfo("Reindexing finished"); |
| 1307 | // To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked): |
| 1308 | chainman.ActiveChainstate().LoadGenesisBlock(); |
| 1309 | } |
| 1310 | |
| 1311 | // -loadblock= |
| 1312 | for (const fs::path& path : import_paths) { |
| 1313 | AutoFile file{fsbridge::fopen(path, "rb")}; |
| 1314 | if (!file.IsNull()) { |
| 1315 | LogInfo("Importing blocks file %s...", fs::PathToString(path)); |
| 1316 | chainman.LoadExternalBlockFile(file); |
| 1317 | if (chainman.m_interrupt) { |
| 1318 | LogInfo("Interrupt requested. Exit block importing."); |
| 1319 | return; |
| 1320 | } |
| 1321 | } else { |
| 1322 | LogWarning("Could not open blocks file %s", fs::PathToString(path)); |
| 1323 | } |
| 1324 | } |
| 1325 | |
| 1326 | // scan for better chains in the block chain database, that are not yet connected in the active best chain |
| 1327 | if (auto result = chainman.ActivateBestChains(); !result) { |
| 1328 | chainman.GetNotifications().fatalError(util::ErrorString(result)); |
| 1329 | } |
| 1330 | // End scope of ImportingNow |
| 1331 | } |
| 1332 | |
| 1333 | std::ostream& operator<<(std::ostream& os, const BlockfileType& type) { |
no test coverage detected