validation: Stricter assumeutxo error handling in InvalidateCoinsDBOnDisk

Currently InvalidateCoinsDBOnDisk is calling AbortNode without an error to the
caller if it fails. Change it to return just return util::Result, and update
the caller to handle the error itself.

This causes the secondary error to be shown below the main error instead of the
other way around.
This commit is contained in:
Ryan Ofsky 2023-06-12 11:48:27 -04:00
parent 9047337d36
commit 1c7d08b9ac
2 changed files with 12 additions and 7 deletions

View file

@ -5411,7 +5411,7 @@ SnapshotCompletionResult ChainstateManager::MaybeCompleteSnapshotValidation(
"restart, the node will resume syncing from %d " "restart, the node will resume syncing from %d "
"without using any snapshot data. " "without using any snapshot data. "
"Please report this incident to %s, including how you obtained the snapshot. " "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."), "helpful in diagnosing the issue that caused this error."),
PACKAGE_NAME, snapshot_tip_height, snapshot_base_height, snapshot_base_height, PACKAGE_BUGREPORT PACKAGE_NAME, snapshot_tip_height, snapshot_base_height, snapshot_base_height, PACKAGE_BUGREPORT
); );
@ -5424,7 +5424,10 @@ SnapshotCompletionResult ChainstateManager::MaybeCompleteSnapshotValidation(
assert(!this->IsUsable(m_snapshot_chainstate.get())); assert(!this->IsUsable(m_snapshot_chainstate.get()));
assert(this->IsUsable(m_ibd_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); shutdown_fnc(user_error);
}; };
@ -5626,7 +5629,7 @@ bool IsBIP30Unspendable(const CBlockIndex& block_index)
(block_index.nHeight==91812 && block_index.GetBlockHash() == uint256S("0x00000000000af0aed4792b1acee3d966af36cf5def14935db8de83d6f9306f2f")); (block_index.nHeight==91812 && block_index.GetBlockHash() == uint256S("0x00000000000af0aed4792b1acee3d966af36cf5def14935db8de83d6f9306f2f"));
} }
void Chainstate::InvalidateCoinsDBOnDisk() util::Result<void> Chainstate::InvalidateCoinsDBOnDisk()
{ {
AssertLockHeld(::cs_main); AssertLockHeld(::cs_main);
// Should never be called on a non-snapshot chainstate. // Should never be called on a non-snapshot chainstate.
@ -5655,13 +5658,14 @@ void Chainstate::InvalidateCoinsDBOnDisk()
LogPrintf("%s: error renaming file '%s' -> '%s': %s\n", LogPrintf("%s: error renaming file '%s' -> '%s': %s\n",
__func__, src_str, dest_str, e.what()); __func__, src_str, dest_str, e.what());
AbortNode(strprintf( return util::Error{strprintf(_(
"Rename of '%s' -> '%s' failed. " "Rename of '%s' -> '%s' failed. "
"You should resolve this by manually moving or deleting the invalid " "You should resolve this by manually moving or deleting the invalid "
"snapshot directory %s, otherwise you will encounter the same error again " "snapshot directory %s, otherwise you will encounter the same error again "
"on the next startup.", "on the next startup."),
src_str, dest_str, src_str)); src_str, dest_str, src_str)};
} }
return {};
} }
const CBlockIndex* ChainstateManager::GetSnapshotBaseBlock() const const CBlockIndex* ChainstateManager::GetSnapshotBaseBlock() const

View file

@ -31,6 +31,7 @@
#include <util/check.h> #include <util/check.h>
#include <util/fs.h> #include <util/fs.h>
#include <util/hasher.h> #include <util/hasher.h>
#include <util/result.h>
#include <util/translation.h> #include <util/translation.h>
#include <versionbits.h> #include <versionbits.h>
@ -810,7 +811,7 @@ private:
* In case of an invalid snapshot, rename the coins leveldb directory so * In case of an invalid snapshot, rename the coins leveldb directory so
* that it can be examined for issue diagnosis. * that it can be examined for issue diagnosis.
*/ */
void InvalidateCoinsDBOnDisk() EXCLUSIVE_LOCKS_REQUIRED(::cs_main); [[nodiscard]] util::Result<void> InvalidateCoinsDBOnDisk() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
friend ChainstateManager; friend ChainstateManager;
}; };