Bitcoin Core 31.99.0
P2P Digital Currency
baseindex_tests.cpp
Go to the documentation of this file.
1// Copyright (c) 2020-present The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
6#include <interfaces/chain.h>
7#include <script/script.h>
9#include <util/byte_units.h>
10#include <util/check.h>
11#include <validation.h>
12
13#include <boost/test/unit_test.hpp>
14
15// Tests of generic BaseIndex functionality that is independent of which
16// concrete index is being used. CoinStatsIndex is used here merely as a
17// convenient instantiation of BaseIndex.
18BOOST_AUTO_TEST_SUITE(baseindex_tests)
19
20// Test that the index does not commit ahead of the chainstate's last
21// flushed block. If it did, a subsequent unclean shutdown would corrupt
22// the index, because during reverting it would require blocks that were
23// never flushed to disk.
24BOOST_FIXTURE_TEST_CASE(baseindex_no_commit_ahead_of_flush, TestChain100Setup)
25{
26 Chainstate& chainstate = Assert(m_node.chainman)->ActiveChainstate();
27 auto sync_index = [&](bool do_flush, int expected_sync_height, int expected_commit_height) {
28 CoinStatsIndex index{interfaces::MakeChain(m_node), /*n_cache_size=*/1_MiB};
29 BOOST_REQUIRE(index.Init());
30 index.Sync();
31 if (do_flush) {
32 chainstate.ForceFlushStateToDisk();
33 m_node.chain->context()->validation_signals->SyncWithValidationInterfaceQueue();
34 }
35 BOOST_CHECK_EQUAL(index.GetSummary().best_block_height, expected_sync_height);
36 index.Stop();
37 // Reload index to see which block data was actually committed.
38 BOOST_REQUIRE(index.Init());
39 BOOST_CHECK_EQUAL(index.GetSummary().best_block_height, expected_commit_height);
40 index.Stop();
41 };
42
43 // Part 1: Sync, then "crash" (stop without flushing). Models a node that
44 // started up, had its index catch up, but never flushed before going down.
45 // The end-of-sync Commit() runs at chain tip (height 100) but
46 // m_last_flushed_block is null, so it is skipped.
47 sync_index(false, 100, 0);
48
49 // Part 2: Restart cleanly. Sync, force a chainstate flush, and drain the
50 // validation queue so the index's ChainStateFlushed callback runs.
51 // Now m_last_flushed_block == tip == 100 and the index can commit.
52 sync_index(true, 100, 100);
53
54 // Part 3: Connect a new block on the chain without flushing
55 // (m_last_flushed_block stays at 100). For a real node this would happen
56 // in parallel with Sync(). Here we do it before Sync() to make the race
57 // state deterministic.
58 CreateAndProcessBlock({}, CScript() << OP_TRUE);
59 sync_index(false, 101, 100);
60}
61
BOOST_FIXTURE_TEST_CASE(baseindex_no_commit_ahead_of_flush, TestChain100Setup)
node::NodeContext m_node
Definition: bitcoin-gui.cpp:47
#define Assert(val)
Identity function.
Definition: check.h:116
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:406
Chainstate stores and provides an API to update our local knowledge of the current best chain.
Definition: validation.h:554
void ForceFlushStateToDisk(bool wipe_cache=true)
Flush all changes to disk.
CoinStatsIndex maintains statistics on the UTXO set.
BOOST_AUTO_TEST_SUITE_END()
BOOST_CHECK_EQUAL(headers.FindFirst("key"), "value")
std::unique_ptr< Chain > MakeChain(node::NodeContext &node)
Return implementation of Chain interface.
@ OP_TRUE
Definition: script.h:85
Testing fixture that pre-creates a 100-block REGTEST-mode block chain.
Definition: setup_common.h:139
std::unique_ptr< ChainstateManager > chainman
Definition: context.h:76
std::unique_ptr< interfaces::Chain > chain
Definition: context.h:80