LCOV - code coverage report
Current view: top level - src/test - validation_chainstate_tests.cpp (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 0 62 0.0 %
Date: 2023-10-05 12:38:51 Functions: 0 21 0.0 %
Branches: 0 0 -

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

Generated by: LCOV version 1.14