diff --git a/src/txdb.cpp b/src/txdb.cpp index 2c39cf2767b..d5c00620d14 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -71,11 +71,24 @@ void CCoinsViewDB::ResizeCache(size_t new_cache_size) std::optional CCoinsViewDB::GetCoin(const COutPoint& outpoint) const { - if (Coin coin; m_db->Read(CoinEntry(&outpoint), coin)) { - Assert(!coin.IsSpent()); // The UTXO database should never contain spent coins - return coin; + Coin coin; + const CDBWrapper::ReadStatus res = m_db->TryRead(CoinEntry(&outpoint), coin); + if (!res) { + // Propagate errors so CCoinsViewErrorCatcher triggers a clean shutdown. + switch (const auto& [err_code, err_msg] = res.error(); err_code) { + case CDBWrapper::ReadFailure::Code::DeserializationError: + throw dbwrapper_error{strprintf("Coin deserialization failure: %s", err_msg)}; + case CDBWrapper::ReadFailure::Code::DatabaseError: + throw dbwrapper_error{strprintf("Coin DB read failure: %s", err_msg)}; + } // no default case, so the compiler can warn about missing cases + std::abort(); // unreachable } - return std::nullopt; + + // Check whether the coin exists + if (!res.value()) return std::nullopt; + // Coin found, ensure UTXO database never contains spent coins + Assert(!coin.IsSpent()); + return coin; } bool CCoinsViewDB::HaveCoin(const COutPoint &outpoint) const {