0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-02-08 10:31:50 -05:00

index: Enable reindex-chainstate with active indexes

This is achieved by letting the index sync thread wait until
reindex-chainstate is finished.

This also disables the pruning check when reindexing the chainstate (which is
incompatible with prune mode) because there would be no chain at this point
in init.
This commit is contained in:
Martin Zumsande 2022-05-23 21:07:29 +02:00
parent 60bec3c82d
commit 97844d9268
7 changed files with 27 additions and 30 deletions

View file

@ -23,6 +23,8 @@
#include <string>
#include <utility>
using node::g_indexes_ready_to_sync;
constexpr uint8_t DB_BEST_BLOCK{'B'};
constexpr auto SYNC_LOG_INTERVAL{30s};
@ -105,7 +107,9 @@ bool BaseIndex::Init()
// datadir and an index enabled. If this is the case, indexation will 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
@ -161,6 +165,12 @@ static const CBlockIndex* NextSyncBlock(const CBlockIndex* pindex_prev, CChain&
void BaseIndex::ThreadSync()
{
SetSyscallSandboxPolicy(SyscallSandboxPolicy::TX_INDEX);
// 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) {
std::chrono::steady_clock::time_point last_log_time{0s};

View file

@ -123,6 +123,7 @@ using node::CalculateCacheSizes;
using node::DEFAULT_PERSIST_MEMPOOL;
using node::DEFAULT_PRINTPRIORITY;
using node::fReindex;
using node::g_indexes_ready_to_sync;
using node::LoadChainstate;
using node::MempoolPath;
using node::NodeContext;
@ -456,7 +457,7 @@ void SetupServerArgs(ArgsManager& argsman)
"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. 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("-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("-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);
@ -982,19 +983,6 @@ bool AppInitParameterInteraction(const ArgsManager& args, bool use_syscall_sandb
if (args.GetIntArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) > 1)
return InitError(Untranslated("Unknown rpcserialversion requested."));
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", "")};
@ -1571,6 +1559,9 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
RegisterValidationInterface(node.peerman.get());
// ********************************************************* Step 8: start 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)) {
if (const auto error{WITH_LOCK(cs_main, return CheckLegacyTxindex(*Assert(chainman.m_blockman.m_block_tree_db)))}) {
return InitError(*error);

View file

@ -27,6 +27,7 @@
namespace node {
std::atomic_bool fReindex(false);
std::atomic_bool g_indexes_ready_to_sync{false};
bool CBlockIndexWorkComparator::operator()(const CBlockIndex* pa, const CBlockIndex* pb) const
{
@ -940,5 +941,6 @@ void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFile
}
} // End scope of ImportingNow
chainman.ActiveChainstate().LoadMempool(mempool_path);
g_indexes_ready_to_sync = true;
}
} // namespace node

View file

@ -47,6 +47,7 @@ static const unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // 128 MiB
static constexpr size_t BLOCK_SERIALIZATION_HEADER_SIZE = 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

View file

@ -155,6 +155,7 @@ BasicTestingSetup::BasicTestingSetup(const ChainType chainType, const std::vecto
noui_connect();
noui_connected = true;
}
node::g_indexes_ready_to_sync = true;
}
BasicTestingSetup::~BasicTestingSetup()

View file

@ -231,18 +231,16 @@ class CoinStatsIndexTest(BitcoinTestFramework):
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 -reindex-chainstate is disallowed with coinstatsindex")
self.log.info("Test that the index works with -reindex-chainstate")
self.stop_node(1)
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'],
)
self.restart_node(1, extra_args=["-coinstatsindex"])
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")
@ -261,6 +259,7 @@ class CoinStatsIndexTest(BitcoinTestFramework):
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)

View file

@ -255,13 +255,6 @@ class CompactFiltersTest(BitcoinTestFramework):
msg = "Error: Unknown -blockfilterindex value abc."
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."""
header = ser_uint256(prev_header)