Skip to content

Commit

Permalink
Merge bitcoin#24789: init, index: disallow indexes when running reind…
Browse files Browse the repository at this point in the history
…ex-chainstate

dac44fc init: disallow reindex-chainstate with optional indexes (Martin Zumsande)
62e1428 doc: Add note that -reindex will rebuild optional indexes (Martin Zumsande)

Pull request description:

  When started together with `-reindex-chainstate`, currently coinstatsindex gets corrupted and the blockfilterindex flatfiles duplicated. See the OP of bitcoin#24630 for more a more detailed explanation on why this happens.

  This is an alternative to bitcoin#24630 which does not wipe and rebuild the indexes but returns an `InitError` when they are activated, thus requiring the user to deactivate them temporarily until the `-reindex-chainstate` run is finished.

  This also disallows `-reindex-chainstate` in combination with `-txindex`, which is not leading to corruption, but currently still rebuilds the index unnecessarily and unexpectedly.

  As a long-term goal, it would be desirable to have the indexes tolerate `reindex-chainstate` by ignoring their `BlockConnected` notifications (there is discussion in bitcoin#24630 about this) or possibly move `reindex-chainstate` option  into a `bitcoin-chainstate` executable, which could also solve the problem. But these would be larger projects - until then, it might be better to disallow the interaction than having corrupted indexes.

  The first commit adjusts the `-reindex` doc to mention that this option does rebuild all active indexes.

ACKs for top commit:
  ryanofsky:
    Code review ACK dac44fc. Just fixed IsArgSet call and edited error messages since last review

Tree-SHA512: c1abf7d350648ae227c3fd6c95d9a54c3bac9de70915275dea1c87cca6d9a76a056c0e306d95ef8cfe4df1f8525b418e0e7a4f52ded3be464041c0dc297f8930
  • Loading branch information
fanquake committed Apr 26, 2022
2 parents 30c1c6e + dac44fc commit 269dcad
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 2 deletions.
17 changes: 15 additions & 2 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,8 +424,8 @@ void SetupServerArgs(ArgsManager& argsman)
argsman.AddArg("-prune=<n>", strprintf("Reduce storage requirements by enabling pruning (deleting) of old blocks. This allows the pruneblockchain RPC to be called to delete specific blocks, and enables automatic pruning of old blocks if a target size in MiB is provided. This mode is incompatible with -txindex and -coinstatsindex. "
"Warning: Reverting this setting requires re-downloading the entire blockchain. "
"(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);
argsman.AddArg("-reindex", "Rebuild chain state and block index from the blk*.dat files on disk", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
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);
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);
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);
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);
#if HAVE_SYSTEM
argsman.AddArg("-startupnotify=<cmd>", "Execute command on startup.", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
Expand Down Expand Up @@ -1033,6 +1033,19 @@ bool AppInitParameterInteraction(const ArgsManager& args, bool use_syscall_sandb
return InitError(_("No proxy server specified. Use -proxy=<ip> or -proxy=<ip:port>."));
}

if (args.GetBoolArg("-reindex-chainstate", false)) {
// indexes that must be deactivated to prevent index corruption, see #24630
if (args.GetBoolArg("-coinstatsindex", DEFAULT_COINSTATSINDEX)) {
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."));
}
if (g_enabled_filter_types.count(BlockFilterType::BASIC)) {
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."));
}
if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) {
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."));
}
}

#if defined(USE_SYSCALL_SANDBOX)
if (args.IsArgSet("-sandbox") && !args.IsArgNegated("-sandbox")) {
const std::string sandbox_arg{args.GetArg("-sandbox", "")};
Expand Down
14 changes: 14 additions & 0 deletions test/functional/feature_coinstatsindex.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,20 @@ def _test_coin_stats_index(self):
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"])
res11 = index_node.gettxoutsetinfo('muhash')
assert_equal(res11, res10)

self.log.info("Test that -reindex-chainstate is disallowed with coinstatsindex")

self.nodes[1].assert_start_raises_init_error(
expected_msg='Error: -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.',
extra_args=['-coinstatsindex', '-reindex-chainstate'],
)

def _test_use_index_option(self):
self.log.info("Test use_index option for nodes running the index")

Expand Down
6 changes: 6 additions & 0 deletions test/functional/p2p_blockfilters.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,12 @@ def run_test(self):
msg = "Error: Cannot set -peerblockfilters without -blockfilterindex."
self.nodes[0].assert_start_raises_init_error(expected_msg=msg)

self.log.info("Test -blockfilterindex with -reindex-chainstate raises an error")
self.nodes[0].assert_start_raises_init_error(
expected_msg='Error: -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.',
extra_args=['-blockfilterindex', '-reindex-chainstate'],
)

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

0 comments on commit 269dcad

Please sign in to comment.