diff --git a/src/init.cpp b/src/init.cpp index 410c574235..e86180017a 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1545,7 +1545,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) } } - if (status == node::ChainstateLoadStatus::FAILURE_INCOMPATIBLE_DB || status == node::ChainstateLoadStatus::FAILURE_INSUFFICIENT_DBCACHE) { + if (status == node::ChainstateLoadStatus::FAILURE_FATAL || status == node::ChainstateLoadStatus::FAILURE_INCOMPATIBLE_DB || status == node::ChainstateLoadStatus::FAILURE_INSUFFICIENT_DBCACHE) { return InitError(error); } diff --git a/src/node/chainstate.cpp b/src/node/chainstate.cpp index 8f997b0594..3900d2e620 100644 --- a/src/node/chainstate.cpp +++ b/src/node/chainstate.cpp @@ -207,7 +207,7 @@ ChainstateLoadResult LoadChainstate(ChainstateManager& chainman, const CacheSize } else if (snapshot_completion == SnapshotCompletionResult::SUCCESS) { LogPrintf("[snapshot] cleaning up unneeded background chainstate, then reinitializing\n"); if (!chainman.ValidatedSnapshotCleanup()) { - AbortNode("Background chainstate cleanup failed unexpectedly."); + return {ChainstateLoadStatus::FAILURE_FATAL, Untranslated("Background chainstate cleanup failed unexpectedly.")}; } // Because ValidatedSnapshotCleanup() has torn down chainstates with diff --git a/src/node/chainstate.h b/src/node/chainstate.h index 77240cafe9..2e35035c28 100644 --- a/src/node/chainstate.h +++ b/src/node/chainstate.h @@ -42,7 +42,8 @@ struct ChainstateLoadOptions { //! and exit cleanly in the interrupted case. enum class ChainstateLoadStatus { SUCCESS, - FAILURE, + FAILURE, //!< Generic failure which reindexing may fix + FAILURE_FATAL, //!< Fatal error which should not prompt to reindex FAILURE_INCOMPATIBLE_DB, FAILURE_INSUFFICIENT_DBCACHE, INTERRUPTED, diff --git a/src/validation.cpp b/src/validation.cpp index 542c1060a9..1fd20ca2c8 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -5412,7 +5412,7 @@ SnapshotCompletionResult ChainstateManager::MaybeCompleteSnapshotValidation( "restart, the node will resume syncing from %d " "without using any snapshot data. " "Please report this incident to %s, including how you obtained the snapshot. " - "The invalid snapshot chainstate has been left on disk in case it is " + "The invalid snapshot chainstate will be left on disk in case it is " "helpful in diagnosing the issue that caused this error."), PACKAGE_NAME, snapshot_tip_height, snapshot_base_height, snapshot_base_height, PACKAGE_BUGREPORT ); @@ -5425,7 +5425,10 @@ SnapshotCompletionResult ChainstateManager::MaybeCompleteSnapshotValidation( assert(!this->IsUsable(m_snapshot_chainstate.get())); assert(this->IsUsable(m_ibd_chainstate.get())); - m_snapshot_chainstate->InvalidateCoinsDBOnDisk(); + auto rename_result = m_snapshot_chainstate->InvalidateCoinsDBOnDisk(); + if (!rename_result) { + user_error = strprintf(Untranslated("%s\n%s"), user_error, util::ErrorString(rename_result)); + } shutdown_fnc(user_error); }; @@ -5627,7 +5630,7 @@ bool IsBIP30Unspendable(const CBlockIndex& block_index) (block_index.nHeight==91812 && block_index.GetBlockHash() == uint256S("0x00000000000af0aed4792b1acee3d966af36cf5def14935db8de83d6f9306f2f")); } -void Chainstate::InvalidateCoinsDBOnDisk() +util::Result Chainstate::InvalidateCoinsDBOnDisk() { AssertLockHeld(::cs_main); // Should never be called on a non-snapshot chainstate. @@ -5656,13 +5659,14 @@ void Chainstate::InvalidateCoinsDBOnDisk() LogPrintf("%s: error renaming file '%s' -> '%s': %s\n", __func__, src_str, dest_str, e.what()); - AbortNode(strprintf( + return util::Error{strprintf(_( "Rename of '%s' -> '%s' failed. " "You should resolve this by manually moving or deleting the invalid " "snapshot directory %s, otherwise you will encounter the same error again " - "on the next startup.", - src_str, dest_str, src_str)); + "on the next startup."), + src_str, dest_str, src_str)}; } + return {}; } const CBlockIndex* ChainstateManager::GetSnapshotBaseBlock() const diff --git a/src/validation.h b/src/validation.h index cb5b291dab..7b215dea6b 100644 --- a/src/validation.h +++ b/src/validation.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -810,7 +811,7 @@ private: * In case of an invalid snapshot, rename the coins leveldb directory so * that it can be examined for issue diagnosis. */ - void InvalidateCoinsDBOnDisk() EXCLUSIVE_LOCKS_REQUIRED(::cs_main); + [[nodiscard]] util::Result InvalidateCoinsDBOnDisk() EXCLUSIVE_LOCKS_REQUIRED(::cs_main); friend ChainstateManager; };