Merge #16355: refactor: move CCoinsViewErrorCatcher out of init.cpp
4f050b91c7
move-onlyish: move CCoinsViewErrorCatcher out of init.cpp (James O'Beirne) Pull request description: This is part of the [assumeutxo project](https://github.com/bitcoin/bitcoin/projects/11): Parent PR: #15606 Issue: #15605 Specification: https://github.com/jamesob/assumeutxo-docs/tree/2019-04-proposal/proposal --- This change moves `CCoinsViewErrorCatcher` out of `init` and into `coins` so that it can later be included in [a `CoinsView` instance](91284964ef (diff-349fbb003d5ae550a2e8fa658e475880R504)
) under `CChainState`. Instead of hardcoding read failure behavior that has knowledge of qt, it accepts error callbacks via `AddReadErrCallback()`. ACKs for top commit: dongcarl: re-ACK4f050b91c7
ryanofsky: utACK4f050b91c7
. Only change since last review is fixing const. Tree-SHA512: eaba21606d15d2b8d0e3db7cec57779ce181af953db1ef4af80a0bc1dfb57923d0befde9d61b7be55c32224744f7fb6bd47d4e4c72f3ccfe6eaf0f4ae3765c17
This commit is contained in:
commit
848f245d04
3 changed files with 48 additions and 25 deletions
|
@ -5,6 +5,7 @@
|
||||||
#include <coins.h>
|
#include <coins.h>
|
||||||
|
|
||||||
#include <consensus/consensus.h>
|
#include <consensus/consensus.h>
|
||||||
|
#include <logging.h>
|
||||||
#include <random.h>
|
#include <random.h>
|
||||||
#include <version.h>
|
#include <version.h>
|
||||||
|
|
||||||
|
@ -258,3 +259,19 @@ const Coin& AccessByTxid(const CCoinsViewCache& view, const uint256& txid)
|
||||||
}
|
}
|
||||||
return coinEmpty;
|
return coinEmpty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CCoinsViewErrorCatcher::GetCoin(const COutPoint &outpoint, Coin &coin) const {
|
||||||
|
try {
|
||||||
|
return CCoinsViewBacked::GetCoin(outpoint, coin);
|
||||||
|
} catch(const std::runtime_error& e) {
|
||||||
|
for (auto f : m_err_callbacks) {
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
LogPrintf("Error reading from database: %s\n", e.what());
|
||||||
|
// Starting the shutdown sequence and returning false to the caller would be
|
||||||
|
// interpreted as 'entry not found' (as opposed to unable to read data), and
|
||||||
|
// could lead to invalid interpretation. Just exit immediately, as we can't
|
||||||
|
// continue anyway, and all writes should be atomic.
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
25
src/coins.h
25
src/coins.h
|
@ -17,6 +17,7 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -315,4 +316,28 @@ void AddCoins(CCoinsViewCache& cache, const CTransaction& tx, int nHeight, bool
|
||||||
//! lookups to database, so it should be used with care.
|
//! lookups to database, so it should be used with care.
|
||||||
const Coin& AccessByTxid(const CCoinsViewCache& cache, const uint256& txid);
|
const Coin& AccessByTxid(const CCoinsViewCache& cache, const uint256& txid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a minimally invasive approach to shutdown on LevelDB read errors from the
|
||||||
|
* chainstate, while keeping user interface out of the common library, which is shared
|
||||||
|
* between bitcoind, and bitcoin-qt and non-server tools.
|
||||||
|
*
|
||||||
|
* Writes do not need similar protection, as failure to write is handled by the caller.
|
||||||
|
*/
|
||||||
|
class CCoinsViewErrorCatcher final : public CCoinsViewBacked
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit CCoinsViewErrorCatcher(CCoinsView* view) : CCoinsViewBacked(view) {}
|
||||||
|
|
||||||
|
void AddReadErrCallback(std::function<void()> f) {
|
||||||
|
m_err_callbacks.emplace_back(std::move(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/** A list of callbacks to execute upon leveldb read error. */
|
||||||
|
std::vector<std::function<void()>> m_err_callbacks;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
#endif // BITCOIN_COINS_H
|
#endif // BITCOIN_COINS_H
|
||||||
|
|
31
src/init.cpp
31
src/init.cpp
|
@ -15,6 +15,7 @@
|
||||||
#include <blockfilter.h>
|
#include <blockfilter.h>
|
||||||
#include <chain.h>
|
#include <chain.h>
|
||||||
#include <chainparams.h>
|
#include <chainparams.h>
|
||||||
|
#include <coins.h>
|
||||||
#include <compat/sanity.h>
|
#include <compat/sanity.h>
|
||||||
#include <consensus/validation.h>
|
#include <consensus/validation.h>
|
||||||
#include <fs.h>
|
#include <fs.h>
|
||||||
|
@ -146,31 +147,6 @@ NODISCARD static bool CreatePidFile()
|
||||||
// shutdown thing.
|
// shutdown thing.
|
||||||
//
|
//
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a minimally invasive approach to shutdown on LevelDB read errors from the
|
|
||||||
* chainstate, while keeping user interface out of the common library, which is shared
|
|
||||||
* between bitcoind, and bitcoin-qt and non-server tools.
|
|
||||||
*/
|
|
||||||
class CCoinsViewErrorCatcher final : public CCoinsViewBacked
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit CCoinsViewErrorCatcher(CCoinsView* view) : CCoinsViewBacked(view) {}
|
|
||||||
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override {
|
|
||||||
try {
|
|
||||||
return CCoinsViewBacked::GetCoin(outpoint, coin);
|
|
||||||
} catch(const std::runtime_error& e) {
|
|
||||||
uiInterface.ThreadSafeMessageBox(_("Error reading from database, shutting down."), "", CClientUIInterface::MSG_ERROR);
|
|
||||||
LogPrintf("Error reading from database: %s\n", e.what());
|
|
||||||
// Starting the shutdown sequence and returning false to the caller would be
|
|
||||||
// interpreted as 'entry not found' (as opposed to unable to read data), and
|
|
||||||
// could lead to invalid interpretation. Just exit immediately, as we can't
|
|
||||||
// continue anyway, and all writes should be atomic.
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Writes do not need similar protection, as failure to write is handled by the caller.
|
|
||||||
};
|
|
||||||
|
|
||||||
static std::unique_ptr<CCoinsViewErrorCatcher> pcoinscatcher;
|
static std::unique_ptr<CCoinsViewErrorCatcher> pcoinscatcher;
|
||||||
static std::unique_ptr<ECCVerifyHandle> globalVerifyHandle;
|
static std::unique_ptr<ECCVerifyHandle> globalVerifyHandle;
|
||||||
|
|
||||||
|
@ -1544,6 +1520,11 @@ bool AppInitMain(InitInterfaces& interfaces)
|
||||||
|
|
||||||
pcoinsdbview.reset(new CCoinsViewDB(nCoinDBCache, false, fReset || fReindexChainState));
|
pcoinsdbview.reset(new CCoinsViewDB(nCoinDBCache, false, fReset || fReindexChainState));
|
||||||
pcoinscatcher.reset(new CCoinsViewErrorCatcher(pcoinsdbview.get()));
|
pcoinscatcher.reset(new CCoinsViewErrorCatcher(pcoinsdbview.get()));
|
||||||
|
pcoinscatcher->AddReadErrCallback([]() {
|
||||||
|
uiInterface.ThreadSafeMessageBox(
|
||||||
|
_("Error reading from database, shutting down."),
|
||||||
|
"", CClientUIInterface::MSG_ERROR);
|
||||||
|
});
|
||||||
|
|
||||||
// If necessary, upgrade from older database format.
|
// If necessary, upgrade from older database format.
|
||||||
// This is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate
|
// This is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate
|
||||||
|
|
Loading…
Add table
Reference in a new issue