| 6297 | } |
| 6298 | |
| 6299 | bool ChainstateManager::ValidatedSnapshotCleanup(Chainstate& validated_cs, Chainstate& unvalidated_cs) |
| 6300 | { |
| 6301 | AssertLockHeld(::cs_main); |
| 6302 | if (unvalidated_cs.m_assumeutxo != Assumeutxo::VALIDATED) { |
| 6303 | // No need to clean up. |
| 6304 | return false; |
| 6305 | } |
| 6306 | |
| 6307 | const fs::path validated_path{validated_cs.StoragePath()}; |
| 6308 | const fs::path assumed_valid_path{unvalidated_cs.StoragePath()}; |
| 6309 | const fs::path delete_path{validated_path + "_todelete"}; |
| 6310 | |
| 6311 | // Since we're going to be moving around the underlying leveldb filesystem content |
| 6312 | // for each chainstate, make sure that the chainstates (and their constituent |
| 6313 | // CoinsViews members) have been destructed first. |
| 6314 | // |
| 6315 | // The caller of this method will be responsible for reinitializing chainstates |
| 6316 | // if they want to continue operation. |
| 6317 | this->ResetChainstates(); |
| 6318 | assert(this->m_chainstates.size() == 0); |
| 6319 | |
| 6320 | LogInfo("[snapshot] deleting background chainstate directory (now unnecessary) (%s)", |
| 6321 | fs::PathToString(validated_path)); |
| 6322 | |
| 6323 | auto rename_failed_abort = [this]( |
| 6324 | fs::path p_old, |
| 6325 | fs::path p_new, |
| 6326 | const fs::filesystem_error& err) { |
| 6327 | LogError("[snapshot] Error renaming path (%s) -> (%s): %s\n", |
| 6328 | fs::PathToString(p_old), fs::PathToString(p_new), err.what()); |
| 6329 | GetNotifications().fatalError(strprintf(_( |
| 6330 | "Rename of '%s' -> '%s' failed. " |
| 6331 | "Cannot clean up the background chainstate leveldb directory."), |
| 6332 | fs::PathToString(p_old), fs::PathToString(p_new))); |
| 6333 | }; |
| 6334 | |
| 6335 | try { |
| 6336 | fs::rename(validated_path, delete_path); |
| 6337 | } catch (const fs::filesystem_error& e) { |
| 6338 | rename_failed_abort(validated_path, delete_path, e); |
| 6339 | throw; |
| 6340 | } |
| 6341 | |
| 6342 | LogInfo("[snapshot] moving snapshot chainstate (%s) to " |
| 6343 | "default chainstate directory (%s)", |
| 6344 | fs::PathToString(assumed_valid_path), fs::PathToString(validated_path)); |
| 6345 | |
| 6346 | try { |
| 6347 | fs::rename(assumed_valid_path, validated_path); |
| 6348 | } catch (const fs::filesystem_error& e) { |
| 6349 | rename_failed_abort(assumed_valid_path, validated_path, e); |
| 6350 | throw; |
| 6351 | } |
| 6352 | |
| 6353 | if (!DeleteCoinsDBFromDisk(delete_path, /*is_snapshot=*/false)) { |
| 6354 | // No need to FatalError because once the unneeded bg chainstate data is |
| 6355 | // moved, it will not interfere with subsequent initialization. |
| 6356 | LogWarning("Deletion of %s failed. Please remove it manually, as the " |
no test coverage detected