Skip to content

Commit 848f245

Browse files
committed
Merge #16355: refactor: move CCoinsViewErrorCatcher out of init.cpp
4f050b9 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](bitcoin/bitcoin@9128496#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-ACK 4f050b9 ryanofsky: utACK 4f050b9. Only change since last review is fixing const. Tree-SHA512: eaba21606d15d2b8d0e3db7cec57779ce181af953db1ef4af80a0bc1dfb57923d0befde9d61b7be55c32224744f7fb6bd47d4e4c72f3ccfe6eaf0f4ae3765c17
2 parents ad4391c + 4f050b9 commit 848f245

File tree

3 files changed

+48
-25
lines changed

3 files changed

+48
-25
lines changed

src/coins.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <coins.h>
66

77
#include <consensus/consensus.h>
8+
#include <logging.h>
89
#include <random.h>
910
#include <version.h>
1011

@@ -258,3 +259,19 @@ const Coin& AccessByTxid(const CCoinsViewCache& view, const uint256& txid)
258259
}
259260
return coinEmpty;
260261
}
262+
263+
bool CCoinsViewErrorCatcher::GetCoin(const COutPoint &outpoint, Coin &coin) const {
264+
try {
265+
return CCoinsViewBacked::GetCoin(outpoint, coin);
266+
} catch(const std::runtime_error& e) {
267+
for (auto f : m_err_callbacks) {
268+
f();
269+
}
270+
LogPrintf("Error reading from database: %s\n", e.what());
271+
// Starting the shutdown sequence and returning false to the caller would be
272+
// interpreted as 'entry not found' (as opposed to unable to read data), and
273+
// could lead to invalid interpretation. Just exit immediately, as we can't
274+
// continue anyway, and all writes should be atomic.
275+
std::abort();
276+
}
277+
}

src/coins.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <assert.h>
1818
#include <stdint.h>
1919

20+
#include <functional>
2021
#include <unordered_map>
2122

2223
/**
@@ -315,4 +316,28 @@ void AddCoins(CCoinsViewCache& cache, const CTransaction& tx, int nHeight, bool
315316
//! lookups to database, so it should be used with care.
316317
const Coin& AccessByTxid(const CCoinsViewCache& cache, const uint256& txid);
317318

319+
/**
320+
* This is a minimally invasive approach to shutdown on LevelDB read errors from the
321+
* chainstate, while keeping user interface out of the common library, which is shared
322+
* between bitcoind, and bitcoin-qt and non-server tools.
323+
*
324+
* Writes do not need similar protection, as failure to write is handled by the caller.
325+
*/
326+
class CCoinsViewErrorCatcher final : public CCoinsViewBacked
327+
{
328+
public:
329+
explicit CCoinsViewErrorCatcher(CCoinsView* view) : CCoinsViewBacked(view) {}
330+
331+
void AddReadErrCallback(std::function<void()> f) {
332+
m_err_callbacks.emplace_back(std::move(f));
333+
}
334+
335+
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override;
336+
337+
private:
338+
/** A list of callbacks to execute upon leveldb read error. */
339+
std::vector<std::function<void()>> m_err_callbacks;
340+
341+
};
342+
318343
#endif // BITCOIN_COINS_H

src/init.cpp

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <blockfilter.h>
1616
#include <chain.h>
1717
#include <chainparams.h>
18+
#include <coins.h>
1819
#include <compat/sanity.h>
1920
#include <consensus/validation.h>
2021
#include <fs.h>
@@ -146,31 +147,6 @@ NODISCARD static bool CreatePidFile()
146147
// shutdown thing.
147148
//
148149

149-
/**
150-
* This is a minimally invasive approach to shutdown on LevelDB read errors from the
151-
* chainstate, while keeping user interface out of the common library, which is shared
152-
* between bitcoind, and bitcoin-qt and non-server tools.
153-
*/
154-
class CCoinsViewErrorCatcher final : public CCoinsViewBacked
155-
{
156-
public:
157-
explicit CCoinsViewErrorCatcher(CCoinsView* view) : CCoinsViewBacked(view) {}
158-
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override {
159-
try {
160-
return CCoinsViewBacked::GetCoin(outpoint, coin);
161-
} catch(const std::runtime_error& e) {
162-
uiInterface.ThreadSafeMessageBox(_("Error reading from database, shutting down."), "", CClientUIInterface::MSG_ERROR);
163-
LogPrintf("Error reading from database: %s\n", e.what());
164-
// Starting the shutdown sequence and returning false to the caller would be
165-
// interpreted as 'entry not found' (as opposed to unable to read data), and
166-
// could lead to invalid interpretation. Just exit immediately, as we can't
167-
// continue anyway, and all writes should be atomic.
168-
abort();
169-
}
170-
}
171-
// Writes do not need similar protection, as failure to write is handled by the caller.
172-
};
173-
174150
static std::unique_ptr<CCoinsViewErrorCatcher> pcoinscatcher;
175151
static std::unique_ptr<ECCVerifyHandle> globalVerifyHandle;
176152

@@ -1544,6 +1520,11 @@ bool AppInitMain(InitInterfaces& interfaces)
15441520

15451521
pcoinsdbview.reset(new CCoinsViewDB(nCoinDBCache, false, fReset || fReindexChainState));
15461522
pcoinscatcher.reset(new CCoinsViewErrorCatcher(pcoinsdbview.get()));
1523+
pcoinscatcher->AddReadErrCallback([]() {
1524+
uiInterface.ThreadSafeMessageBox(
1525+
_("Error reading from database, shutting down."),
1526+
"", CClientUIInterface::MSG_ERROR);
1527+
});
15471528

15481529
// If necessary, upgrade from older database format.
15491530
// This is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate

0 commit comments

Comments
 (0)