Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14864981
D17714.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
7 KB
Subscribers
None
D17714.id.diff
View Options
diff --git a/src/index/base.cpp b/src/index/base.cpp
--- a/src/index/base.cpp
+++ b/src/index/base.cpp
@@ -24,6 +24,8 @@
#include <string>
#include <utility>
+using node::g_indexes_ready_to_sync;
+
constexpr uint8_t DB_BEST_BLOCK{'B'};
constexpr int64_t SYNC_LOG_INTERVAL = 30; // secon
@@ -83,7 +85,17 @@
if (locator.IsNull()) {
SetBestBlockIndex(nullptr);
} else {
- SetBestBlockIndex(m_chainstate->FindForkInGlobalIndex(locator));
+ // Setting the best block to the locator's top block. If it is not part
+ // of the best chain, we will rewind to the fork point during index sync
+ const CBlockIndex *locator_index{
+ m_chainstate->m_blockman.LookupBlockIndex(locator.vHave.at(0))};
+ if (!locator_index) {
+ return InitError(
+ strprintf(Untranslated("%s: best block of the index not found. "
+ "Please rebuild the index."),
+ GetName()));
+ }
+ SetBestBlockIndex(locator_index);
}
// Note: this will latch to true immediately if the user starts up with an
@@ -91,7 +103,10 @@
// happen solely via `BlockConnected` signals until, possibly, the next
// restart.
m_synced = m_best_block_index.load() == active_chain.Tip();
- if (!m_synced) {
+
+ // Skip pruning check if indexes are not ready to sync (because
+ // reindex-chainstate has wiped the chain).
+ if (!m_synced && g_indexes_ready_to_sync) {
bool prune_violation = false;
if (!m_best_block_index) {
// index is not built yet
@@ -154,6 +169,14 @@
}
void BaseIndex::ThreadSync() {
+ // Wait for a possible reindex-chainstate to finish until continuing
+ // with the index sync
+ while (!g_indexes_ready_to_sync) {
+ if (!m_interrupt.sleep_for(std::chrono::milliseconds(500))) {
+ return;
+ }
+ }
+
const CBlockIndex *pindex = m_best_block_index.load();
if (!m_synced) {
int64_t last_log_time = 0;
diff --git a/src/init.cpp b/src/init.cpp
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -124,6 +124,7 @@
using node::CalculateCacheSizes;
using node::DEFAULT_PERSIST_MEMPOOL;
using node::fReindex;
+using node::g_indexes_ready_to_sync;
using node::KernelNotifications;
using node::LoadChainstate;
using node::MempoolPath;
@@ -629,7 +630,8 @@
ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
argsman.AddArg(
"-reindex",
- "Rebuild chain state and block index from the blk*.dat files on disk",
+ "Rebuild chain state and block index from the blk*.dat files on disk."
+ " This will also rebuild active optional indexes.",
ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
argsman.AddArg(
"-settings=<file>",
@@ -2633,6 +2635,12 @@
config.SetCashAddrEncoding(args.GetBoolArg("-usecashaddr", true));
// Step 8: load indexers
+
+ // If reindex-chainstate was specified, delay syncing indexes until
+ // ThreadImport has reindexed the chain
+ if (!fReindexChainState) {
+ g_indexes_ready_to_sync = true;
+ }
if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) {
auto result{
WITH_LOCK(cs_main, return CheckLegacyTxindex(*Assert(
diff --git a/src/node/blockstorage.h b/src/node/blockstorage.h
--- a/src/node/blockstorage.h
+++ b/src/node/blockstorage.h
@@ -51,6 +51,7 @@
CMessageHeader::MESSAGE_START_SIZE + sizeof(unsigned int);
extern std::atomic_bool fReindex;
+extern std::atomic_bool g_indexes_ready_to_sync;
// Because validation code takes pointers to the map's CBlockIndex objects, if
// we ever switch to another associative container, we need to either use a
diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp
--- a/src/node/blockstorage.cpp
+++ b/src/node/blockstorage.cpp
@@ -29,6 +29,7 @@
namespace node {
std::atomic_bool fReindex(false);
+std::atomic_bool g_indexes_ready_to_sync{false};
std::vector<CBlockIndex *> BlockManager::GetAllBlockIndices() {
AssertLockHeld(cs_main);
@@ -1030,5 +1031,6 @@
}
} // End scope of ImportingNow
chainman.ActiveChainstate().LoadMempool(mempool_path);
+ g_indexes_ready_to_sync = true;
}
} // namespace node
diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp
--- a/src/test/util/setup_common.cpp
+++ b/src/test/util/setup_common.cpp
@@ -151,6 +151,7 @@
noui_connect();
noui_connected = true;
}
+ node::g_indexes_ready_to_sync = true;
}
BasicTestingSetup::~BasicTestingSetup() {
diff --git a/test/functional/feature_coinstatsindex.py b/test/functional/feature_coinstatsindex.py
--- a/test/functional/feature_coinstatsindex.py
+++ b/test/functional/feature_coinstatsindex.py
@@ -25,7 +25,7 @@
self.supports_cli = False
self.extra_args = [
[
- "-automaticunparking=1",
+ "-noparkdeepreorg",
],
[
"-coinstatsindex",
@@ -38,6 +38,7 @@
self._test_use_index_option()
self._test_reorg_index()
self._test_index_rejects_hash_serialized()
+ self._test_init_index_after_reorg()
def block_sanity_check(self, block_info):
block_subsidy = 50_000_000
@@ -48,6 +49,11 @@
+ block_info["unspendable"],
)
+ def sync_index_node(self):
+ self.wait_until(
+ lambda: self.nodes[1].getindexinfo()["coinstatsindex"]["synced"] is True
+ )
+
def _test_coin_stats_index(self):
node = self.nodes[0]
index_node = self.nodes[1]
@@ -239,6 +245,20 @@
res10 = index_node.gettxoutsetinfo("muhash")
assert res8["txouts"] < res10["txouts"]
+ self.log.info("Test that the index works with -reindex")
+
+ self.restart_node(1, extra_args=["-coinstatsindex", "-reindex"])
+ self.sync_index_node()
+ res11 = index_node.gettxoutsetinfo("muhash")
+ assert_equal(res11, res10)
+
+ self.log.info("Test that the index works with -reindex-chainstate")
+
+ self.restart_node(1, extra_args=["-coinstatsindex", "-reindex-chainstate"])
+ self.sync_index_node()
+ res12 = index_node.gettxoutsetinfo("muhash")
+ assert_equal(res12, res10)
+
def _test_use_index_option(self):
self.log.info("Test use_index option for nodes running the index")
@@ -259,6 +279,7 @@
index_node = self.nodes[1]
reorg_blocks = self.generatetoaddress(index_node, 2, getnewdestination()[2])
reorg_block = reorg_blocks[1]
+ self.sync_index_node()
res_invalid = index_node.gettxoutsetinfo("muhash")
index_node.invalidateblock(reorg_blocks[0])
assert_equal(index_node.gettxoutsetinfo("muhash")["height"], 110)
@@ -319,6 +340,30 @@
use_index=use_index,
)
+ def _test_init_index_after_reorg(self):
+ self.log.info("Test a reorg while the index is deactivated")
+ index_node = self.nodes[1]
+ block = self.nodes[0].getbestblockhash()
+ self.generate(index_node, 2, sync_fun=self.no_op)
+ self.sync_index_node()
+
+ # Restart without index
+ self.restart_node(1, extra_args=[])
+ self.connect_nodes(0, 1)
+ index_node.invalidateblock(block)
+ self.generatetoaddress(index_node, 5, getnewdestination()[2])
+ res = index_node.gettxoutsetinfo(
+ hash_type="muhash", hash_or_height=None, use_index=False
+ )
+
+ # Restart with index that still has its best block on the old chain
+ self.restart_node(1, extra_args=self.extra_args[1])
+ self.sync_index_node()
+ res1 = index_node.gettxoutsetinfo(
+ hash_type="muhash", hash_or_height=None, use_index=True
+ )
+ assert_equal(res["muhash"], res1["muhash"])
+
if __name__ == "__main__":
CoinStatsIndexTest().main()
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, May 20, 23:56 (19 m, 9 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5866181
Default Alt Text
D17714.id.diff (7 KB)
Attached To
D17714: index: fix reindex-chainstate with active indexes
Event Timeline
Log In to Comment