-
Notifications
You must be signed in to change notification settings - Fork 364
Expand file tree
/
Copy pathbaseindex_tests.cpp
More file actions
62 lines (54 loc) · 2.69 KB
/
Copy pathbaseindex_tests.cpp
File metadata and controls
62 lines (54 loc) · 2.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// 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.
// The end-of-sync Commit() runs at chain tip (height 100) but
// m_last_flushed_block is null, so it is skipped.
sync_index(false, 100, 0);
// Part 2: Restart cleanly. Sync, force a chainstate flush, and drain the
// validation queue so the index's ChainStateFlushed callback runs.
// Now m_last_flushed_block == tip == 100 and the index can commit.
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, 100);
}
BOOST_AUTO_TEST_SUITE_END()