Skip to content

Commit dac44fc

Browse files
committed
init: disallow reindex-chainstate with optional indexes
It currently leads to corruption (coinstatsindex) or data duplication (blockfilterindex), so disable it.
1 parent 62e1428 commit dac44fc

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

src/init.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ void SetupServerArgs(ArgsManager& argsman)
424424
"Warning: Reverting this setting requires re-downloading the entire blockchain. "
425425
"(default: 0 = disable pruning blocks, 1 = allow manual pruning via RPC, >=%u = automatically prune block files to stay under the specified target size in MiB)", MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
426426
argsman.AddArg("-reindex", "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);
427-
argsman.AddArg("-reindex-chainstate", "Rebuild chain state from the currently indexed blocks. When in pruning mode or if blocks on disk might be corrupted, use full -reindex instead.", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
427+
argsman.AddArg("-reindex-chainstate", "Rebuild chain state from the currently indexed blocks. When in pruning mode or if blocks on disk might be corrupted, use full -reindex instead. Deactivate all optional indexes before running this.", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
428428
argsman.AddArg("-settings=<file>", strprintf("Specify path to dynamic settings data file. Can be disabled with -nosettings. File is written at runtime and not meant to be edited by users (use %s instead for custom settings). Relative paths will be prefixed by datadir location. (default: %s)", BITCOIN_CONF_FILENAME, BITCOIN_SETTINGS_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
429429
#if HAVE_SYSTEM
430430
argsman.AddArg("-startupnotify=<cmd>", "Execute command on startup.", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
@@ -1031,6 +1031,19 @@ bool AppInitParameterInteraction(const ArgsManager& args, bool use_syscall_sandb
10311031
return InitError(_("No proxy server specified. Use -proxy=<ip> or -proxy=<ip:port>."));
10321032
}
10331033

1034+
if (args.GetBoolArg("-reindex-chainstate", false)) {
1035+
// indexes that must be deactivated to prevent index corruption, see #24630
1036+
if (args.GetBoolArg("-coinstatsindex", DEFAULT_COINSTATSINDEX)) {
1037+
return InitError(_("-reindex-chainstate option is not compatible with -coinstatsindex. Please temporarily disable coinstatsindex while using -reindex-chainstate, or replace -reindex-chainstate with -reindex to fully rebuild all indexes."));
1038+
}
1039+
if (g_enabled_filter_types.count(BlockFilterType::BASIC)) {
1040+
return InitError(_("-reindex-chainstate option is not compatible with -blockfilterindex. Please temporarily disable blockfilterindex while using -reindex-chainstate, or replace -reindex-chainstate with -reindex to fully rebuild all indexes."));
1041+
}
1042+
if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) {
1043+
return InitError(_("-reindex-chainstate option is not compatible with -txindex. Please temporarily disable txindex while using -reindex-chainstate, or replace -reindex-chainstate with -reindex to fully rebuild all indexes."));
1044+
}
1045+
}
1046+
10341047
#if defined(USE_SYSCALL_SANDBOX)
10351048
if (args.IsArgSet("-sandbox") && !args.IsArgNegated("-sandbox")) {
10361049
const std::string sandbox_arg{args.GetArg("-sandbox", "")};

test/functional/feature_coinstatsindex.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,20 @@ def _test_coin_stats_index(self):
223223
res10 = index_node.gettxoutsetinfo('muhash')
224224
assert(res8['txouts'] < res10['txouts'])
225225

226+
self.log.info("Test that the index works with -reindex")
227+
228+
self.restart_node(1, extra_args=["-coinstatsindex", "-reindex"])
229+
res11 = index_node.gettxoutsetinfo('muhash')
230+
assert_equal(res11, res10)
231+
232+
self.log.info("Test that -reindex-chainstate is disallowed with coinstatsindex")
233+
234+
self.nodes[1].assert_start_raises_init_error(
235+
expected_msg='Error: -reindex-chainstate option is not compatible with -coinstatsindex. '
236+
'Please temporarily disable coinstatsindex while using -reindex-chainstate, or replace -reindex-chainstate with -reindex to fully rebuild all indexes.',
237+
extra_args=['-coinstatsindex', '-reindex-chainstate'],
238+
)
239+
226240
def _test_use_index_option(self):
227241
self.log.info("Test use_index option for nodes running the index")
228242

test/functional/p2p_blockfilters.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,12 @@ def run_test(self):
250250
msg = "Error: Cannot set -peerblockfilters without -blockfilterindex."
251251
self.nodes[0].assert_start_raises_init_error(expected_msg=msg)
252252

253+
self.log.info("Test -blockfilterindex with -reindex-chainstate raises an error")
254+
self.nodes[0].assert_start_raises_init_error(
255+
expected_msg='Error: -reindex-chainstate option is not compatible with -blockfilterindex. '
256+
'Please temporarily disable blockfilterindex while using -reindex-chainstate, or replace -reindex-chainstate with -reindex to fully rebuild all indexes.',
257+
extra_args=['-blockfilterindex', '-reindex-chainstate'],
258+
)
253259

254260
def compute_last_header(prev_header, hashes):
255261
"""Compute the last filter header from a starting header and a sequence of filter hashes."""

0 commit comments

Comments
 (0)