LCOV - code coverage report
Current view: top level - src/test - validation_chainstatemanager_tests.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 84 84 100.0 %
Date: 2020-09-26 01:30:44 Functions: 23 23 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2019-2020 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 <consensus/validation.h>
       7             : #include <random.h>
       8             : #include <sync.h>
       9             : #include <test/util/setup_common.h>
      10             : #include <uint256.h>
      11             : #include <validation.h>
      12             : #include <validationinterface.h>
      13             : 
      14             : #include <vector>
      15             : 
      16             : #include <boost/test/unit_test.hpp>
      17             : 
      18          89 : BOOST_FIXTURE_TEST_SUITE(validation_chainstatemanager_tests, TestingSetup)
      19             : 
      20             : //! Basic tests for ChainstateManager.
      21             : //!
      22             : //! First create a legacy (IBD) chainstate, then create a snapshot chainstate.
      23          95 : BOOST_AUTO_TEST_CASE(chainstatemanager)
      24             : {
      25           1 :     ChainstateManager manager;
      26           1 :     CTxMemPool mempool;
      27           1 :     std::vector<CChainState*> chainstates;
      28           1 :     const CChainParams& chainparams = Params();
      29             : 
      30             :     // Create a legacy (IBD) chainstate.
      31             :     //
      32           2 :     CChainState& c1 = *WITH_LOCK(::cs_main, return &manager.InitializeChainstate(mempool));
      33           1 :     chainstates.push_back(&c1);
      34           1 :     c1.InitCoinsDB(
      35             :         /* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
      36           2 :     WITH_LOCK(::cs_main, c1.InitCoinsCache(1 << 23));
      37             : 
      38           1 :     BOOST_CHECK(!manager.IsSnapshotActive());
      39           1 :     BOOST_CHECK(!manager.IsSnapshotValidated());
      40           1 :     BOOST_CHECK(!manager.IsBackgroundIBD(&c1));
      41           1 :     auto all = manager.GetAll();
      42           1 :     BOOST_CHECK_EQUAL_COLLECTIONS(all.begin(), all.end(), chainstates.begin(), chainstates.end());
      43             : 
      44           1 :     auto& active_chain = manager.ActiveChain();
      45           1 :     BOOST_CHECK_EQUAL(&active_chain, &c1.m_chain);
      46             : 
      47           1 :     BOOST_CHECK_EQUAL(manager.ActiveHeight(), -1);
      48             : 
      49           1 :     auto active_tip = manager.ActiveTip();
      50           1 :     auto exp_tip = c1.m_chain.Tip();
      51           1 :     BOOST_CHECK_EQUAL(active_tip, exp_tip);
      52             : 
      53           1 :     auto& validated_cs = manager.ValidatedChainstate();
      54           1 :     BOOST_CHECK_EQUAL(&validated_cs, &c1);
      55             : 
      56             :     // Create a snapshot-based chainstate.
      57             :     //
      58           2 :     CChainState& c2 = *WITH_LOCK(::cs_main, return &manager.InitializeChainstate(mempool, GetRandHash()));
      59           1 :     chainstates.push_back(&c2);
      60           1 :     c2.InitCoinsDB(
      61             :         /* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
      62           2 :     WITH_LOCK(::cs_main, c2.InitCoinsCache(1 << 23));
      63             :     // Unlike c1, which doesn't have any blocks. Gets us different tip, height.
      64           1 :     c2.LoadGenesisBlock(chainparams);
      65           1 :     BlockValidationState _;
      66           1 :     BOOST_CHECK(c2.ActivateBestChain(_, chainparams, nullptr));
      67             : 
      68           1 :     BOOST_CHECK(manager.IsSnapshotActive());
      69           1 :     BOOST_CHECK(!manager.IsSnapshotValidated());
      70           1 :     BOOST_CHECK(manager.IsBackgroundIBD(&c1));
      71           1 :     BOOST_CHECK(!manager.IsBackgroundIBD(&c2));
      72           1 :     auto all2 = manager.GetAll();
      73           1 :     BOOST_CHECK_EQUAL_COLLECTIONS(all2.begin(), all2.end(), chainstates.begin(), chainstates.end());
      74             : 
      75           1 :     auto& active_chain2 = manager.ActiveChain();
      76           1 :     BOOST_CHECK_EQUAL(&active_chain2, &c2.m_chain);
      77             : 
      78           1 :     BOOST_CHECK_EQUAL(manager.ActiveHeight(), 0);
      79             : 
      80           1 :     auto active_tip2 = manager.ActiveTip();
      81           1 :     auto exp_tip2 = c2.m_chain.Tip();
      82           1 :     BOOST_CHECK_EQUAL(active_tip2, exp_tip2);
      83             : 
      84             :     // Ensure that these pointers actually correspond to different
      85             :     // CCoinsViewCache instances.
      86           1 :     BOOST_CHECK(exp_tip != exp_tip2);
      87             : 
      88           1 :     auto& validated_cs2 = manager.ValidatedChainstate();
      89           1 :     BOOST_CHECK_EQUAL(&validated_cs2, &c1);
      90             : 
      91           1 :     auto& validated_chain = manager.ValidatedChain();
      92           1 :     BOOST_CHECK_EQUAL(&validated_chain, &c1.m_chain);
      93             : 
      94           1 :     auto validated_tip = manager.ValidatedTip();
      95           1 :     exp_tip = c1.m_chain.Tip();
      96           1 :     BOOST_CHECK_EQUAL(validated_tip, exp_tip);
      97             : 
      98             :     // Let scheduler events finish running to avoid accessing memory that is going to be unloaded
      99           1 :     SyncWithValidationInterfaceQueue();
     100             : 
     101           2 :     WITH_LOCK(::cs_main, manager.Unload());
     102           1 : }
     103             : 
     104             : //! Test rebalancing the caches associated with each chainstate.
     105          95 : BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches)
     106             : {
     107           1 :     ChainstateManager manager;
     108           1 :     CTxMemPool mempool;
     109           1 :     size_t max_cache = 10000;
     110           1 :     manager.m_total_coinsdb_cache = max_cache;
     111           1 :     manager.m_total_coinstip_cache = max_cache;
     112             : 
     113           1 :     std::vector<CChainState*> chainstates;
     114             : 
     115             :     // Create a legacy (IBD) chainstate.
     116             :     //
     117           2 :     CChainState& c1 = *WITH_LOCK(cs_main, return &manager.InitializeChainstate(mempool));
     118           1 :     chainstates.push_back(&c1);
     119           1 :     c1.InitCoinsDB(
     120             :         /* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
     121             : 
     122             :     {
     123           1 :         LOCK(::cs_main);
     124           1 :         c1.InitCoinsCache(1 << 23);
     125           1 :         c1.CoinsTip().SetBestBlock(InsecureRand256());
     126           1 :         manager.MaybeRebalanceCaches();
     127           1 :     }
     128             : 
     129           1 :     BOOST_CHECK_EQUAL(c1.m_coinstip_cache_size_bytes, max_cache);
     130           1 :     BOOST_CHECK_EQUAL(c1.m_coinsdb_cache_size_bytes, max_cache);
     131             : 
     132             :     // Create a snapshot-based chainstate.
     133             :     //
     134           2 :     CChainState& c2 = *WITH_LOCK(cs_main, return &manager.InitializeChainstate(mempool, GetRandHash()));
     135           1 :     chainstates.push_back(&c2);
     136           1 :     c2.InitCoinsDB(
     137             :         /* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
     138             : 
     139             :     {
     140           1 :         LOCK(::cs_main);
     141           1 :         c2.InitCoinsCache(1 << 23);
     142           1 :         c2.CoinsTip().SetBestBlock(InsecureRand256());
     143           1 :         manager.MaybeRebalanceCaches();
     144           1 :     }
     145             : 
     146             :     // Since both chainstates are considered to be in initial block download,
     147             :     // the snapshot chainstate should take priority.
     148           1 :     BOOST_CHECK_CLOSE(c1.m_coinstip_cache_size_bytes, max_cache * 0.05, 1);
     149           1 :     BOOST_CHECK_CLOSE(c1.m_coinsdb_cache_size_bytes, max_cache * 0.05, 1);
     150           1 :     BOOST_CHECK_CLOSE(c2.m_coinstip_cache_size_bytes, max_cache * 0.95, 1);
     151           1 :     BOOST_CHECK_CLOSE(c2.m_coinsdb_cache_size_bytes, max_cache * 0.95, 1);
     152           1 : }
     153             : 
     154          89 : BOOST_AUTO_TEST_SUITE_END()

Generated by: LCOV version 1.15