Skip to content

Commit 2b081c4

Browse files
jamesobMarcoFalke
andcommitted
test: add basic tests for ChainstateManager
Feedback incorporated from Russell Yanofsky. Co-authored-by: MarcoFalke <[email protected]>
1 parent 4ae29f5 commit 2b081c4

File tree

4 files changed

+107
-0
lines changed

4 files changed

+107
-0
lines changed

src/Makefile.test.include

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ BITCOIN_TESTS =\
231231
test/uint256_tests.cpp \
232232
test/util_tests.cpp \
233233
test/validation_block_tests.cpp \
234+
test/validation_chainstatemanager_tests.cpp \
234235
test/validation_flush_tests.cpp \
235236
test/versionbits_tests.cpp
236237

src/qt/test/apptests.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ void AppTests::appTests()
8282
// Reset global state to avoid interfering with later tests.
8383
AbortShutdown();
8484
UnloadBlockIndex();
85+
g_chainman.Reset();
8586
}
8687

8788
//! Entry point for BitcoinGUI tests.

src/test/util/setup_common.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha
111111
GetMainSignals().RegisterBackgroundSignalScheduler(*g_rpc_node->scheduler);
112112

113113
pblocktree.reset(new CBlockTreeDB(1 << 20, true));
114+
114115
g_chainman.InitializeChainstate();
115116
::ChainstateActive().InitCoinsDB(
116117
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Copyright (c) 2019 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+
//
5+
#include <chainparams.h>
6+
#include <random.h>
7+
#include <uint256.h>
8+
#include <consensus/validation.h>
9+
#include <sync.h>
10+
#include <test/util/setup_common.h>
11+
#include <validation.h>
12+
13+
#include <vector>
14+
15+
#include <boost/test/unit_test.hpp>
16+
17+
BOOST_FIXTURE_TEST_SUITE(validation_chainstatemanager_tests, TestingSetup)
18+
19+
//! Basic tests for ChainstateManager.
20+
//!
21+
//! First create a legacy (IBD) chainstate, then create a snapshot chainstate.
22+
BOOST_AUTO_TEST_CASE(chainstatemanager)
23+
{
24+
ChainstateManager manager;
25+
std::vector<CChainState*> chainstates;
26+
const CChainParams& chainparams = Params();
27+
28+
// Create a legacy (IBD) chainstate.
29+
//
30+
ENTER_CRITICAL_SECTION(cs_main);
31+
CChainState& c1 = manager.InitializeChainstate();
32+
LEAVE_CRITICAL_SECTION(cs_main);
33+
chainstates.push_back(&c1);
34+
c1.InitCoinsDB(
35+
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
36+
WITH_LOCK(::cs_main, c1.InitCoinsCache());
37+
38+
BOOST_CHECK(!manager.IsSnapshotActive());
39+
BOOST_CHECK(!manager.IsSnapshotValidated());
40+
BOOST_CHECK(!manager.IsBackgroundIBD(&c1));
41+
auto all = manager.GetAll();
42+
BOOST_CHECK_EQUAL_COLLECTIONS(all.begin(), all.end(), chainstates.begin(), chainstates.end());
43+
44+
auto& active_chain = manager.ActiveChain();
45+
BOOST_CHECK_EQUAL(&active_chain, &c1.m_chain);
46+
47+
BOOST_CHECK_EQUAL(manager.ActiveHeight(), -1);
48+
49+
auto active_tip = manager.ActiveTip();
50+
auto exp_tip = c1.m_chain.Tip();
51+
BOOST_CHECK_EQUAL(active_tip, exp_tip);
52+
53+
auto& validated_cs = manager.ValidatedChainstate();
54+
BOOST_CHECK_EQUAL(&validated_cs, &c1);
55+
56+
// Create a snapshot-based chainstate.
57+
//
58+
ENTER_CRITICAL_SECTION(cs_main);
59+
CChainState& c2 = manager.InitializeChainstate(GetRandHash());
60+
LEAVE_CRITICAL_SECTION(cs_main);
61+
chainstates.push_back(&c2);
62+
c2.InitCoinsDB(
63+
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
64+
WITH_LOCK(::cs_main, c2.InitCoinsCache());
65+
// Unlike c1, which doesn't have any blocks. Gets us different tip, height.
66+
c2.LoadGenesisBlock(chainparams);
67+
BlockValidationState _;
68+
BOOST_CHECK(c2.ActivateBestChain(_, chainparams, nullptr));
69+
70+
BOOST_CHECK(manager.IsSnapshotActive());
71+
BOOST_CHECK(!manager.IsSnapshotValidated());
72+
BOOST_CHECK(manager.IsBackgroundIBD(&c1));
73+
BOOST_CHECK(!manager.IsBackgroundIBD(&c2));
74+
auto all2 = manager.GetAll();
75+
BOOST_CHECK_EQUAL_COLLECTIONS(all2.begin(), all2.end(), chainstates.begin(), chainstates.end());
76+
77+
auto& active_chain2 = manager.ActiveChain();
78+
BOOST_CHECK_EQUAL(&active_chain2, &c2.m_chain);
79+
80+
BOOST_CHECK_EQUAL(manager.ActiveHeight(), 0);
81+
82+
auto active_tip2 = manager.ActiveTip();
83+
auto exp_tip2 = c2.m_chain.Tip();
84+
BOOST_CHECK_EQUAL(active_tip2, exp_tip2);
85+
86+
// Ensure that these pointers actually correspond to different
87+
// CCoinsViewCache instances.
88+
BOOST_CHECK(exp_tip != exp_tip2);
89+
90+
auto& validated_cs2 = manager.ValidatedChainstate();
91+
BOOST_CHECK_EQUAL(&validated_cs2, &c1);
92+
93+
auto& validated_chain = manager.ValidatedChain();
94+
BOOST_CHECK_EQUAL(&validated_chain, &c1.m_chain);
95+
96+
auto validated_tip = manager.ValidatedTip();
97+
exp_tip = c1.m_chain.Tip();
98+
BOOST_CHECK_EQUAL(validated_tip, exp_tip);
99+
100+
// Avoid triggering the address sanitizer.
101+
WITH_LOCK(::cs_main, manager.Unload());
102+
}
103+
104+
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)