index: Avoid async shutdown on init error

This commit is contained in:
MarcoFalke 2021-04-28 14:01:37 +02:00
parent 2e30e328a7
commit faad68fcd4
No known key found for this signature in database
GPG Key ID: CE2B75697E69A548
7 changed files with 23 additions and 17 deletions

View File

@ -98,9 +98,7 @@ bool BaseIndex::Init()
} }
} }
if (prune_violation) { if (prune_violation) {
// throw error and graceful shutdown if we can't build the index return InitError(strprintf(Untranslated("%s best block of the index goes beyond pruned data. Please disable the index or reindex (which will download the whole blockchain again)"), GetName()));
FatalError("%s: %s best block of the index goes beyond pruned data. Please disable the index or reindex (which will download the whole blockchain again)", __func__, GetName());
return false;
} }
} }
return true; return true;
@ -339,17 +337,17 @@ void BaseIndex::Interrupt()
m_interrupt(); m_interrupt();
} }
void BaseIndex::Start() bool BaseIndex::Start()
{ {
// Need to register this ValidationInterface before running Init(), so that // Need to register this ValidationInterface before running Init(), so that
// callbacks are not missed if Init sets m_synced to true. // callbacks are not missed if Init sets m_synced to true.
RegisterValidationInterface(this); RegisterValidationInterface(this);
if (!Init()) { if (!Init()) {
FatalError("%s: %s failed to initialize", __func__, GetName()); return false;
return;
} }
m_thread_sync = std::thread(&util::TraceThread, GetName(), [this] { ThreadSync(); }); m_thread_sync = std::thread(&util::TraceThread, GetName(), [this] { ThreadSync(); });
return true;
} }
void BaseIndex::Stop() void BaseIndex::Stop()

View File

@ -84,7 +84,7 @@ protected:
const CBlockIndex* CurrentIndex() { return m_best_block_index.load(); }; const CBlockIndex* CurrentIndex() { return m_best_block_index.load(); };
/// Initialize internal state from the database and block index. /// Initialize internal state from the database and block index.
virtual bool Init(); [[nodiscard]] virtual bool Init();
/// Write update index entries for a newly connected block. /// Write update index entries for a newly connected block.
virtual bool WriteBlock(const CBlock& block, const CBlockIndex* pindex) { return true; } virtual bool WriteBlock(const CBlock& block, const CBlockIndex* pindex) { return true; }
@ -117,7 +117,7 @@ public:
/// Start initializes the sync state and registers the instance as a /// Start initializes the sync state and registers the instance as a
/// ValidationInterface so that it stays in sync with blockchain updates. /// ValidationInterface so that it stays in sync with blockchain updates.
void Start(); [[nodiscard]] bool Start();
/// Stops the instance from staying in sync with blockchain updates. /// Stops the instance from staying in sync with blockchain updates.
void Stop(); void Stop();

View File

@ -1550,17 +1550,23 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
// ********************************************************* Step 8: start indexers // ********************************************************* Step 8: start indexers
if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) { if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) {
g_txindex = std::make_unique<TxIndex>(nTxIndexCache, false, fReindex); g_txindex = std::make_unique<TxIndex>(nTxIndexCache, false, fReindex);
g_txindex->Start(); if (!g_txindex->Start()) {
return false;
}
} }
for (const auto& filter_type : g_enabled_filter_types) { for (const auto& filter_type : g_enabled_filter_types) {
InitBlockFilterIndex(filter_type, filter_index_cache, false, fReindex); InitBlockFilterIndex(filter_type, filter_index_cache, false, fReindex);
GetBlockFilterIndex(filter_type)->Start(); if (!GetBlockFilterIndex(filter_type)->Start()) {
return false;
}
} }
if (args.GetBoolArg("-coinstatsindex", DEFAULT_COINSTATSINDEX)) { if (args.GetBoolArg("-coinstatsindex", DEFAULT_COINSTATSINDEX)) {
g_coin_stats_index = std::make_unique<CoinStatsIndex>(/* cache size */ 0, false, fReindex); g_coin_stats_index = std::make_unique<CoinStatsIndex>(/* cache size */ 0, false, fReindex);
g_coin_stats_index->Start(); if (!g_coin_stats_index->Start()) {
return false;
}
} }
// ********************************************************* Step 9: load wallet // ********************************************************* Step 9: load wallet

View File

@ -131,7 +131,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
// BlockUntilSyncedToCurrentChain should return false before index is started. // BlockUntilSyncedToCurrentChain should return false before index is started.
BOOST_CHECK(!filter_index.BlockUntilSyncedToCurrentChain()); BOOST_CHECK(!filter_index.BlockUntilSyncedToCurrentChain());
filter_index.Start(); BOOST_REQUIRE(filter_index.Start());
// Allow filter index to catch up with the block index. // Allow filter index to catch up with the block index.
constexpr int64_t timeout_ms = 10 * 1000; constexpr int64_t timeout_ms = 10 * 1000;

View File

@ -32,7 +32,7 @@ BOOST_FIXTURE_TEST_CASE(coinstatsindex_initial_sync, TestChain100Setup)
// is started. // is started.
BOOST_CHECK(!coin_stats_index.BlockUntilSyncedToCurrentChain()); BOOST_CHECK(!coin_stats_index.BlockUntilSyncedToCurrentChain());
coin_stats_index.Start(); BOOST_REQUIRE(coin_stats_index.Start());
// Allow the CoinStatsIndex to catch up with the block index that is syncing // Allow the CoinStatsIndex to catch up with the block index that is syncing
// in a background thread. // in a background thread.

View File

@ -27,7 +27,7 @@ BOOST_FIXTURE_TEST_CASE(txindex_initial_sync, TestChain100Setup)
// BlockUntilSyncedToCurrentChain should return false before txindex is started. // BlockUntilSyncedToCurrentChain should return false before txindex is started.
BOOST_CHECK(!txindex.BlockUntilSyncedToCurrentChain()); BOOST_CHECK(!txindex.BlockUntilSyncedToCurrentChain());
txindex.Start(); BOOST_REQUIRE(txindex.Start());
// Allow tx index to catch up with the block index. // Allow tx index to catch up with the block index.
constexpr int64_t timeout_ms = 10 * 1000; constexpr int64_t timeout_ms = 10 * 1000;

View File

@ -54,11 +54,13 @@ class FeatureBlockfilterindexPruneTest(BitcoinTestFramework):
self.stop_node(0) self.stop_node(0)
self.log.info("make sure we get an init error when starting the node again with block filters") self.log.info("make sure we get an init error when starting the node again with block filters")
with self.nodes[0].assert_debug_log(["basic block filter index best block of the index goes beyond pruned data. Please disable the index or reindex (which will download the whole blockchain again)"]): self.nodes[0].assert_start_raises_init_error(
self.nodes[0].assert_start_raises_init_error(extra_args=["-fastprune", "-prune=1", "-blockfilterindex=1"]) extra_args=["-fastprune", "-prune=1", "-blockfilterindex=1"],
expected_msg="Error: basic block filter index best block of the index goes beyond pruned data. Please disable the index or reindex (which will download the whole blockchain again)",
)
self.log.info("make sure the node starts again with the -reindex arg") self.log.info("make sure the node starts again with the -reindex arg")
self.start_node(0, extra_args = ["-fastprune", "-prune=1", "-blockfilterindex", "-reindex"]) self.start_node(0, extra_args=["-fastprune", "-prune=1", "-blockfilterindex", "-reindex"])
if __name__ == '__main__': if __name__ == '__main__':