mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-07-12 23:20:23 +02:00
test: add test for index commits ahead of the last flushed block
Co-authored-by: Ryan Ofsky <ryan@ofsky.org>
This commit is contained in:
@@ -15,6 +15,7 @@ add_executable(test_bitcoin
|
||||
base32_tests.cpp
|
||||
base58_tests.cpp
|
||||
base64_tests.cpp
|
||||
baseindex_tests.cpp
|
||||
bech32_tests.cpp
|
||||
bip32_tests.cpp
|
||||
bip324_tests.cpp
|
||||
|
||||
59
src/test/baseindex_tests.cpp
Normal file
59
src/test/baseindex_tests.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright (c) 2020-present The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <index/coinstatsindex.h>
|
||||
#include <interfaces/chain.h>
|
||||
#include <script/script.h>
|
||||
#include <test/util/setup_common.h>
|
||||
#include <util/byte_units.h>
|
||||
#include <util/check.h>
|
||||
#include <validation.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
// Tests of generic BaseIndex functionality that is independent of which
|
||||
// concrete index is being used. CoinStatsIndex is used here merely as a
|
||||
// convenient instantiation of BaseIndex.
|
||||
BOOST_AUTO_TEST_SUITE(baseindex_tests)
|
||||
|
||||
// Test that the index does not commit ahead of the chainstate's last
|
||||
// flushed block. If it did, a subsequent unclean shutdown would corrupt
|
||||
// the index, because during reverting it would require blocks that were
|
||||
// never flushed to disk.
|
||||
BOOST_FIXTURE_TEST_CASE(baseindex_no_commit_ahead_of_flush, TestChain100Setup)
|
||||
{
|
||||
Chainstate& chainstate = Assert(m_node.chainman)->ActiveChainstate();
|
||||
auto sync_index = [&](bool do_flush, int expected_sync_height, int expected_commit_height) {
|
||||
CoinStatsIndex index{interfaces::MakeChain(m_node), /*n_cache_size=*/1_MiB};
|
||||
BOOST_REQUIRE(index.Init());
|
||||
index.Sync();
|
||||
if (do_flush) {
|
||||
chainstate.ForceFlushStateToDisk();
|
||||
m_node.chain->context()->validation_signals->SyncWithValidationInterfaceQueue();
|
||||
}
|
||||
BOOST_CHECK_EQUAL(index.GetSummary().best_block_height, expected_sync_height);
|
||||
index.Stop();
|
||||
// Reload index to see which block data was actually committed.
|
||||
BOOST_REQUIRE(index.Init());
|
||||
BOOST_CHECK_EQUAL(index.GetSummary().best_block_height, expected_commit_height);
|
||||
index.Stop();
|
||||
};
|
||||
|
||||
// Part 1: Sync, then "crash" (stop without flushing). Models a node that
|
||||
// started up, had its index catch up, but never flushed before going down.
|
||||
sync_index(false, 100, 100);
|
||||
|
||||
// Part 2: Restart cleanly. Sync, force a chainstate flush, and drain the
|
||||
// validation queue so the index's ChainStateFlushed callback runs.
|
||||
sync_index(true, 100, 100);
|
||||
|
||||
// Part 3: Connect a new block on the chain without flushing
|
||||
// (m_last_flushed_block stays at 100). For a real node this would happen
|
||||
// in parallel with Sync(). Here we do it before Sync() to make the race
|
||||
// state deterministic.
|
||||
CreateAndProcessBlock({}, CScript() << OP_TRUE);
|
||||
sync_index(false, 101, 101);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
Reference in New Issue
Block a user