LCOV - code coverage report
Current view: top level - src/test - validation_chainstate_tests.cpp (source / functions) Coverage Total Hit
Test: total_coverage.info Lines: 96.2 % 53 51
Test Date: 2024-07-07 05:05:19 Functions: 100.0 % 8 8
Branches: 50.0 % 272 136

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2020-2022 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 <rpc/blockchain.h>
       9                 :             : #include <sync.h>
      10                 :             : #include <test/util/chainstate.h>
      11                 :             : #include <test/util/coins.h>
      12                 :             : #include <test/util/random.h>
      13                 :             : #include <test/util/setup_common.h>
      14                 :             : #include <uint256.h>
      15                 :             : #include <util/check.h>
      16                 :             : #include <validation.h>
      17                 :             : 
      18                 :             : #include <vector>
      19                 :             : 
      20                 :             : #include <boost/test/unit_test.hpp>
      21                 :             : 
      22                 :             : BOOST_FIXTURE_TEST_SUITE(validation_chainstate_tests, ChainTestingSetup)
      23                 :             : 
      24                 :             : //! Test resizing coins-related Chainstate caches during runtime.
      25                 :             : //!
      26   [ +  -  +  -  :           7 : BOOST_AUTO_TEST_CASE(validation_chainstate_resize_caches)
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
      27                 :             : {
      28                 :           1 :     ChainstateManager& manager = *Assert(m_node.chainman);
      29                 :           1 :     CTxMemPool& mempool = *Assert(m_node.mempool);
      30   [ +  -  +  - ]:           3 :     Chainstate& c1 = WITH_LOCK(cs_main, return manager.InitializeChainstate(&mempool));
      31         [ +  - ]:           1 :     c1.InitCoinsDB(
      32                 :             :         /*cache_size_bytes=*/1 << 23, /*in_memory=*/true, /*should_wipe=*/false);
      33         [ +  - ]:           3 :     WITH_LOCK(::cs_main, c1.InitCoinsCache(1 << 23));
      34   [ +  -  +  - ]:           2 :     BOOST_REQUIRE(c1.LoadGenesisBlock()); // Need at least one block loaded to be able to flush caches
      35                 :             : 
      36                 :             :     // Add a coin to the in-memory cache, upsize once, then downsize.
      37                 :           1 :     {
      38                 :           1 :         LOCK(::cs_main);
      39   [ +  -  +  - ]:           1 :         const auto outpoint = AddTestCoin(c1.CoinsTip());
      40                 :             : 
      41                 :             :         // Set a meaningless bestblock value in the coinsview cache - otherwise we won't
      42                 :             :         // flush during ResizecoinsCaches() and will subsequently hit an assertion.
      43   [ +  -  +  - ]:           2 :         c1.CoinsTip().SetBestBlock(InsecureRand256());
      44                 :             : 
      45   [ +  -  +  -  :           2 :         BOOST_CHECK(c1.CoinsTip().HaveCoinInCache(outpoint));
          +  -  +  -  +  
                      - ]
      46                 :             : 
      47         [ +  - ]:           1 :         c1.ResizeCoinsCaches(
      48                 :             :             1 << 24,  // upsizing the coinsview cache
      49                 :             :             1 << 22  // downsizing the coinsdb cache
      50                 :             :         );
      51                 :             : 
      52                 :             :         // View should still have the coin cached, since we haven't destructed the cache on upsize.
      53   [ +  -  +  -  :           2 :         BOOST_CHECK(c1.CoinsTip().HaveCoinInCache(outpoint));
          +  -  +  -  +  
                      - ]
      54                 :             : 
      55         [ +  - ]:           1 :         c1.ResizeCoinsCaches(
      56                 :             :             1 << 22,  // downsizing the coinsview cache
      57                 :             :             1 << 23  // upsizing the coinsdb cache
      58                 :             :         );
      59                 :             : 
      60                 :             :         // The view cache should be empty since we had to destruct to downsize.
      61   [ +  -  +  -  :           2 :         BOOST_CHECK(!c1.CoinsTip().HaveCoinInCache(outpoint));
          +  -  +  -  +  
                      - ]
      62                 :           1 :     }
      63                 :           1 : }
      64                 :             : 
      65                 :             : //! Test UpdateTip behavior for both active and background chainstates.
      66                 :             : //!
      67                 :             : //! When run on the background chainstate, UpdateTip should do a subset
      68                 :             : //! of what it does for the active chainstate.
      69   [ +  -  +  -  :           7 : BOOST_FIXTURE_TEST_CASE(chainstate_update_tip, TestChain100Setup)
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
      70                 :             : {
      71                 :           1 :     ChainstateManager& chainman = *Assert(m_node.chainman);
      72                 :           1 :     uint256 curr_tip = ::g_best_block;
      73                 :             : 
      74                 :             :     // Mine 10 more blocks, putting at us height 110 where a valid assumeutxo value can
      75                 :             :     // be found.
      76                 :           1 :     mineBlocks(10);
      77                 :             : 
      78                 :             :     // After adding some blocks to the tip, best block should have changed.
      79         [ +  - ]:           2 :     BOOST_CHECK(::g_best_block != curr_tip);
      80                 :             : 
      81                 :             :     // Grab block 1 from disk; we'll add it to the background chain later.
      82                 :           1 :     std::shared_ptr<CBlock> pblockone = std::make_shared<CBlock>();
      83                 :           1 :     {
      84         [ +  - ]:           1 :         LOCK(::cs_main);
      85   [ +  -  +  -  :           2 :         chainman.m_blockman.ReadBlockFromDisk(*pblockone, *chainman.ActiveChain()[1]);
                   +  - ]
      86                 :           0 :     }
      87                 :             : 
      88   [ +  -  +  -  :           2 :     BOOST_REQUIRE(CreateAndActivateUTXOSnapshot(
             +  -  +  - ]
      89                 :             :         this, NoMalleation, /*reset_chainstate=*/ true));
      90                 :             : 
      91                 :             :     // Ensure our active chain is the snapshot chainstate.
      92   [ +  -  +  -  :           4 :     BOOST_CHECK(WITH_LOCK(::cs_main, return chainman.IsSnapshotActive()));
             +  -  +  - ]
      93                 :             : 
      94                 :           1 :     curr_tip = ::g_best_block;
      95                 :             : 
      96                 :             :     // Mine a new block on top of the activated snapshot chainstate.
      97         [ +  - ]:           1 :     mineBlocks(1);  // Defined in TestChain100Setup.
      98                 :             : 
      99                 :             :     // After adding some blocks to the snapshot tip, best block should have changed.
     100   [ +  -  +  -  :           2 :     BOOST_CHECK(::g_best_block != curr_tip);
                   +  - ]
     101                 :             : 
     102                 :           1 :     curr_tip = ::g_best_block;
     103                 :             : 
     104   [ +  -  +  -  :           1 :     BOOST_CHECK_EQUAL(chainman.GetAll().size(), 2);
                   +  - ]
     105                 :             : 
     106   [ +  -  +  -  :           2 :     Chainstate& background_cs{*Assert([&]() -> Chainstate* {
                   +  - ]
     107                 :             :         for (Chainstate* cs : chainman.GetAll()) {
     108                 :             :             if (cs != &chainman.ActiveChainstate()) {
     109                 :             :                 return cs;
     110                 :             :             }
     111                 :             :         }
     112                 :             :         return nullptr;
     113                 :           1 :     }())};
     114                 :             : 
     115                 :             :     // Append the first block to the background chain.
     116         [ +  - ]:           1 :     BlockValidationState state;
     117                 :           1 :     CBlockIndex* pindex = nullptr;
     118         [ +  - ]:           1 :     const CChainParams& chainparams = Params();
     119                 :           1 :     bool newblock = false;
     120                 :             : 
     121                 :             :     // TODO: much of this is inlined from ProcessNewBlock(); just reuse PNB()
     122                 :             :     // once it is changed to support multiple chainstates.
     123                 :           1 :     {
     124         [ +  - ]:           1 :         LOCK(::cs_main);
     125         [ +  - ]:           1 :         bool checked = CheckBlock(*pblockone, state, chainparams.GetConsensus());
     126   [ +  -  +  -  :           2 :         BOOST_CHECK(checked);
                   +  - ]
     127   [ +  -  +  -  :           2 :         bool accepted = chainman.AcceptBlock(
                   +  - ]
     128                 :             :             pblockone, state, &pindex, true, nullptr, &newblock, true);
     129   [ +  -  +  -  :           2 :         BOOST_CHECK(accepted);
                   +  - ]
     130                 :           0 :     }
     131                 :             : 
     132                 :             :     // UpdateTip is called here
     133   [ +  -  +  -  :           2 :     bool block_added = background_cs.ActivateBestChain(state, pblockone);
                   +  - ]
     134                 :             : 
     135                 :             :     // Ensure tip is as expected
     136   [ +  -  +  -  :           2 :     BOOST_CHECK_EQUAL(background_cs.m_chain.Tip()->GetBlockHash(), pblockone->GetHash());
             +  -  +  - ]
     137                 :             : 
     138                 :             :     // g_best_block should be unchanged after adding a block to the background
     139                 :             :     // validation chain.
     140   [ +  -  +  -  :           2 :     BOOST_CHECK(block_added);
                   +  - ]
     141   [ +  -  +  - ]:           1 :     BOOST_CHECK_EQUAL(curr_tip, ::g_best_block);
     142         [ +  - ]:           2 : }
     143                 :             : 
     144                 :             : BOOST_AUTO_TEST_SUITE_END()
        

Generated by: LCOV version 2.0-1