Bitcoin Core  31.0.0
P2P Digital Currency
coinstatsindex_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 
5 #include <chainparams.h>
6 #include <index/coinstatsindex.h>
7 #include <interfaces/chain.h>
8 #include <kernel/coinstats.h>
9 #include <kernel/types.h>
10 #include <test/util/setup_common.h>
11 #include <test/util/validation.h>
12 #include <validation.h>
13 
14 #include <boost/test/unit_test.hpp>
15 
17 
18 BOOST_AUTO_TEST_SUITE(coinstatsindex_tests)
19 
20 BOOST_FIXTURE_TEST_CASE(coinstatsindex_initial_sync, TestChain100Setup)
21 {
22  CoinStatsIndex coin_stats_index{interfaces::MakeChain(m_node), 1 << 20, true};
23  BOOST_REQUIRE(coin_stats_index.Init());
24 
25  const CBlockIndex* block_index;
26  {
27  LOCK(cs_main);
28  block_index = m_node.chainman->ActiveChain().Tip();
29  }
30 
31  // CoinStatsIndex should not be found before it is started.
32  BOOST_CHECK(!coin_stats_index.LookUpStats(*block_index));
33 
34  // BlockUntilSyncedToCurrentChain should return false before CoinStatsIndex
35  // is started.
36  BOOST_CHECK(!coin_stats_index.BlockUntilSyncedToCurrentChain());
37 
38  coin_stats_index.Sync();
39 
40  // Check that CoinStatsIndex works for genesis block.
41  const CBlockIndex* genesis_block_index;
42  {
43  LOCK(cs_main);
44  genesis_block_index = m_node.chainman->ActiveChain().Genesis();
45  }
46  BOOST_CHECK(coin_stats_index.LookUpStats(*genesis_block_index));
47 
48  // Check that CoinStatsIndex updates with new blocks.
49  BOOST_CHECK(coin_stats_index.LookUpStats(*block_index));
50 
51  const CScript script_pub_key{CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG};
52  std::vector<CMutableTransaction> noTxns;
53  CreateAndProcessBlock(noTxns, script_pub_key);
54 
55  // Let the CoinStatsIndex to catch up again.
56  BOOST_CHECK(coin_stats_index.BlockUntilSyncedToCurrentChain());
57 
58  const CBlockIndex* new_block_index;
59  {
60  LOCK(cs_main);
61  new_block_index = m_node.chainman->ActiveChain().Tip();
62  }
63  BOOST_CHECK(coin_stats_index.LookUpStats(*new_block_index));
64 
65  BOOST_CHECK(block_index != new_block_index);
66 
67  // Shutdown sequence (c.f. Shutdown() in init.cpp)
68  coin_stats_index.Stop();
69 }
70 
71 // Test shutdown between BlockConnected and ChainStateFlushed notifications,
72 // make sure index is not corrupted and is able to reload.
73 BOOST_FIXTURE_TEST_CASE(coinstatsindex_unclean_shutdown, TestChain100Setup)
74 {
75  Chainstate& chainstate = Assert(m_node.chainman)->ActiveChainstate();
76  const CChainParams& params = Params();
77  {
79  BOOST_REQUIRE(index.Init());
80  index.Sync();
81  std::shared_ptr<const CBlock> new_block;
82  CBlockIndex* new_block_index = nullptr;
83  {
84  const CScript script_pub_key{CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG};
85  const CBlock block = this->CreateBlock({}, script_pub_key, chainstate);
86 
87  new_block = std::make_shared<CBlock>(block);
88 
89  LOCK(cs_main);
91  BOOST_CHECK(CheckBlock(block, state, params.GetConsensus()));
92  BOOST_CHECK(m_node.chainman->AcceptBlock(new_block, state, &new_block_index, true, nullptr, nullptr, true));
93  CCoinsViewCache view(&chainstate.CoinsTip());
94  BOOST_CHECK(chainstate.ConnectBlock(block, state, new_block_index, view));
95  }
96  // Send block connected notification, then stop the index without
97  // sending a chainstate flushed notification. Prior to #24138, this
98  // would cause the index to be corrupted and fail to reload.
99  ValidationInterfaceTest::BlockConnected(ChainstateRole{}, index, new_block, new_block_index);
100  index.Stop();
101  }
102 
103  {
105  BOOST_REQUIRE(index.Init());
106  // Make sure the index can be loaded.
107  BOOST_REQUIRE(index.StartBackgroundSync());
108  index.Stop();
109  }
110 }
111 
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(
Definition: validation.h:686
is a home for simple enum and struct type definitions that can be used internally by functions in the...
Definition: block.h:73
node::NodeContext m_node
Definition: bitcoin-gui.cpp:43
Information about chainstate that notifications are sent from.
Definition: types.h:18
BOOST_FIXTURE_TEST_CASE(coinstatsindex_initial_sync, TestChain100Setup)
static void BlockConnected(const kernel::ChainstateRole &role, CValidationInterface &obj, const std::shared_ptr< const CBlock > &block, const CBlockIndex *pindex)
Definition: validation.cpp:46
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system...
Definition: chainparams.h:76
Chainstate stores and provides an API to update our local knowledge of the current best chain...
Definition: validation.h:550
bool ActivateBestChain(BlockValidationState &state, std::shared_ptr< const CBlock > pblock=nullptr) LOCKS_EXCLUDED(DisconnectResult DisconnectBlock(const CBlock &block, const CBlockIndex *pindex, CCoinsViewCache &view) EXCLUSIVE_LOCKS_REQUIRED(boo ConnectBlock)(const CBlock &block, BlockValidationState &state, CBlockIndex *pindex, CCoinsViewCache &view, bool fJustCheck=false) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Find the best known block, and make it the tip of the block chain.
Definition: validation.h:781
#define LOCK(cs)
Definition: sync.h:258
BOOST_AUTO_TEST_SUITE_END()
CoinStatsIndex maintains statistics on the UTXO set.
bool CheckBlock(const CBlock &block, BlockValidationState &state, const Consensus::Params &consensusParams, bool fCheckPOW, bool fCheckMerkleRoot)
Functions for validating blocks and updating the block tree.
Testing fixture that pre-creates a 100-block REGTEST-mode block chain.
Definition: setup_common.h:146
std::vector< unsigned char > ToByteVector(const T &in)
Definition: script.h:67
std::unique_ptr< Chain > MakeChain(node::NodeContext &node)
Return implementation of Chain interface.
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: chain.h:93
const CChainParams & Params()
Return the currently selected parameters.
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:404
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:89
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:367
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
Definition: cs_main.cpp:8
std::unique_ptr< ChainstateManager > chainman
Definition: context.h:72
#define Assert(val)
Identity function.
Definition: check.h:113
#define BOOST_CHECK(expr)
Definition: object.cpp:16