Skip to content

Commit 430e702

Browse files
committed
refactor: index, decouple 'Init' from 'Start'
So indexes can be initialized without spawning the sync thread. This makes asynchronous indexes startup possible in the following commits.
1 parent 225e213 commit 430e702

File tree

7 files changed

+35
-23
lines changed

7 files changed

+35
-23
lines changed

src/index/base.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,13 @@ BaseIndex::~BaseIndex()
8181

8282
bool BaseIndex::Init()
8383
{
84+
// m_chainstate member gives indexing code access to node internals. It is
85+
// removed in followup https://github.com/bitcoin/bitcoin/pull/24230
86+
m_chainstate = &m_chain->context()->chainman->ActiveChainstate();
87+
// Register to validation interface before setting the 'm_synced' flag, so that
88+
// callbacks are not missed once m_synced is true.
89+
RegisterValidationInterface(this);
90+
8491
CBlockLocator locator;
8592
if (!GetDB().ReadBestBlock(locator)) {
8693
locator.SetNull();
@@ -147,6 +154,7 @@ bool BaseIndex::Init()
147154
// datadir and an index enabled. If this is the case, indexation will happen solely
148155
// via `BlockConnected` signals until, possibly, the next restart.
149156
m_synced = synced;
157+
m_init = true;
150158
return true;
151159
}
152160

@@ -401,15 +409,9 @@ void BaseIndex::Interrupt()
401409
m_interrupt();
402410
}
403411

404-
bool BaseIndex::Start()
412+
bool BaseIndex::StartBackgroundSync()
405413
{
406-
// m_chainstate member gives indexing code access to node internals. It is
407-
// removed in followup https://github.com/bitcoin/bitcoin/pull/24230
408-
m_chainstate = &m_chain->context()->chainman->ActiveChainstate();
409-
// Need to register this ValidationInterface before running Init(), so that
410-
// callbacks are not missed if Init sets m_synced to true.
411-
RegisterValidationInterface(this);
412-
if (!Init()) return false;
414+
if (!m_init) throw std::logic_error("Error: Cannot start a non-initialized index");
413415

414416
m_thread_sync = std::thread(&util::TraceThread, GetName(), [this] { ThreadSync(); });
415417
return true;

src/index/base.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ class BaseIndex : public CValidationInterface
5454
};
5555

5656
private:
57+
/// Whether the index has been initialized or not.
58+
std::atomic<bool> m_init{false};
5759
/// Whether the index is in sync with the main chain. The flag is flipped
5860
/// from false to true once, after which point this starts processing
5961
/// ValidationInterface notifications to stay in sync.
@@ -69,9 +71,6 @@ class BaseIndex : public CValidationInterface
6971
std::thread m_thread_sync;
7072
CThreadInterrupt m_interrupt;
7173

72-
/// Read best block locator and check that data needed to sync has not been pruned.
73-
bool Init();
74-
7574
/// Sync the index with the block index starting from the current best block.
7675
/// Intended to be run in its own thread, m_thread_sync, and can be
7776
/// interrupted with m_interrupt. Once the index gets in sync, the m_synced
@@ -142,9 +141,12 @@ class BaseIndex : public CValidationInterface
142141

143142
void Interrupt();
144143

145-
/// Start initializes the sync state and registers the instance as a
146-
/// ValidationInterface so that it stays in sync with blockchain updates.
147-
[[nodiscard]] bool Start();
144+
/// Initializes the sync state and registers the instance to the
145+
/// validation interface so that it stays in sync with blockchain updates.
146+
[[nodiscard]] bool Init();
147+
148+
/// Starts the initial sync process.
149+
[[nodiscard]] bool StartBackgroundSync();
148150

149151
/// Stops the instance from staying in sync with blockchain updates.
150152
void Stop();

src/init.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1567,8 +1567,11 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
15671567
node.indexes.emplace_back(g_coin_stats_index.get());
15681568
}
15691569

1570+
// Init indexes
1571+
for (auto index : node.indexes) if (!index->Init()) return false;
1572+
15701573
// Now that all indexes are loaded, start them
1571-
StartIndexes(node);
1574+
if (!StartIndexBackgroundSync(node)) return false;
15721575

15731576
// ********************************************************* Step 9: load wallet
15741577
for (const auto& client : node.chain_clients) {
@@ -1876,8 +1879,8 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
18761879
return true;
18771880
}
18781881

1879-
bool StartIndexes(NodeContext& node)
1882+
bool StartIndexBackgroundSync(NodeContext& node)
18801883
{
1881-
for (auto index : node.indexes) if (!index->Start()) return false;
1884+
for (auto index : node.indexes) if (!index->StartBackgroundSync()) return false;
18821885
return true;
18831886
}

src/init.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,6 @@ bool AppInitMain(node::NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip
7474
void SetupServerArgs(ArgsManager& argsman);
7575

7676
/** Validates requirements to run the indexes and spawns each index initial sync thread */
77-
bool StartIndexes(node::NodeContext& node);
77+
bool StartIndexBackgroundSync(node::NodeContext& node);
7878

7979
#endif // BITCOIN_INIT_H

src/test/blockfilter_index_tests.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ bool BuildChainTestingSetup::BuildChain(const CBlockIndex* pindex,
113113
BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
114114
{
115115
BlockFilterIndex filter_index(interfaces::MakeChain(m_node), BlockFilterType::BASIC, 1 << 20, true);
116+
BOOST_REQUIRE(filter_index.Init());
116117

117118
uint256 last_header;
118119

@@ -139,7 +140,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
139140
// BlockUntilSyncedToCurrentChain should return false before index is started.
140141
BOOST_CHECK(!filter_index.BlockUntilSyncedToCurrentChain());
141142

142-
BOOST_REQUIRE(filter_index.Start());
143+
BOOST_REQUIRE(filter_index.StartBackgroundSync());
143144

144145
// Allow filter index to catch up with the block index.
145146
IndexWaitSynced(filter_index);

src/test/coinstatsindex_tests.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ BOOST_AUTO_TEST_SUITE(coinstatsindex_tests)
1818
BOOST_FIXTURE_TEST_CASE(coinstatsindex_initial_sync, TestChain100Setup)
1919
{
2020
CoinStatsIndex coin_stats_index{interfaces::MakeChain(m_node), 1 << 20, true};
21+
BOOST_REQUIRE(coin_stats_index.Init());
2122

2223
const CBlockIndex* block_index;
2324
{
@@ -32,7 +33,7 @@ BOOST_FIXTURE_TEST_CASE(coinstatsindex_initial_sync, TestChain100Setup)
3233
// is started.
3334
BOOST_CHECK(!coin_stats_index.BlockUntilSyncedToCurrentChain());
3435

35-
BOOST_REQUIRE(coin_stats_index.Start());
36+
BOOST_REQUIRE(coin_stats_index.StartBackgroundSync());
3637

3738
IndexWaitSynced(coin_stats_index);
3839

@@ -83,7 +84,8 @@ BOOST_FIXTURE_TEST_CASE(coinstatsindex_unclean_shutdown, TestChain100Setup)
8384
const CChainParams& params = Params();
8485
{
8586
CoinStatsIndex index{interfaces::MakeChain(m_node), 1 << 20};
86-
BOOST_REQUIRE(index.Start());
87+
BOOST_REQUIRE(index.Init());
88+
BOOST_REQUIRE(index.StartBackgroundSync());
8789
IndexWaitSynced(index);
8890
std::shared_ptr<const CBlock> new_block;
8991
CBlockIndex* new_block_index = nullptr;
@@ -109,8 +111,9 @@ BOOST_FIXTURE_TEST_CASE(coinstatsindex_unclean_shutdown, TestChain100Setup)
109111

110112
{
111113
CoinStatsIndex index{interfaces::MakeChain(m_node), 1 << 20};
114+
BOOST_REQUIRE(index.Init());
112115
// Make sure the index can be loaded.
113-
BOOST_REQUIRE(index.Start());
116+
BOOST_REQUIRE(index.StartBackgroundSync());
114117
index.Stop();
115118
}
116119
}

src/test/txindex_tests.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ BOOST_AUTO_TEST_SUITE(txindex_tests)
1717
BOOST_FIXTURE_TEST_CASE(txindex_initial_sync, TestChain100Setup)
1818
{
1919
TxIndex txindex(interfaces::MakeChain(m_node), 1 << 20, true);
20+
BOOST_REQUIRE(txindex.Init());
2021

2122
CTransactionRef tx_disk;
2223
uint256 block_hash;
@@ -29,7 +30,7 @@ BOOST_FIXTURE_TEST_CASE(txindex_initial_sync, TestChain100Setup)
2930
// BlockUntilSyncedToCurrentChain should return false before txindex is started.
3031
BOOST_CHECK(!txindex.BlockUntilSyncedToCurrentChain());
3132

32-
BOOST_REQUIRE(txindex.Start());
33+
BOOST_REQUIRE(txindex.StartBackgroundSync());
3334

3435
// Allow tx index to catch up with the block index.
3536
IndexWaitSynced(txindex);

0 commit comments

Comments
 (0)