LCOV - code coverage report
Current view: top level - src/test - baseindex_tests.cpp (source / functions) Coverage Total Hit
Test: test_bitcoin_coverage.info Lines: 100.0 % 20 20
Test Date: 2026-07-17 06:52:43 Functions: 100.0 % 3 3
Branches: 50.8 % 120 61

             Branch data     Line data    Source code
       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 <index/coinstatsindex.h>
       6                 :             : #include <interfaces/chain.h>
       7                 :             : #include <script/script.h>
       8                 :             : #include <test/util/setup_common.h>
       9                 :             : #include <util/byte_units.h>
      10                 :             : #include <util/check.h>
      11                 :             : #include <validation.h>
      12                 :             : 
      13                 :             : #include <boost/test/unit_test.hpp>
      14                 :             : 
      15                 :             : // Tests of generic BaseIndex functionality that is independent of which
      16                 :             : // concrete index is being used. CoinStatsIndex is used here merely as a
      17                 :             : // convenient instantiation of BaseIndex.
      18                 :             : BOOST_AUTO_TEST_SUITE(baseindex_tests)
      19                 :             : 
      20                 :             : // Test that the index does not commit ahead of the chainstate's last
      21                 :             : // flushed block. If it did, a subsequent unclean shutdown would corrupt
      22                 :             : // the index, because during reverting it would require blocks that were
      23                 :             : // never flushed to disk.
      24   [ +  -  +  -  :           7 : BOOST_FIXTURE_TEST_CASE(baseindex_no_commit_ahead_of_flush, TestChain100Setup)
          +  -  +  -  -  
          +  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
                      - ]
      25                 :             : {
      26         [ -  + ]:           1 :     Chainstate& chainstate = Assert(m_node.chainman)->ActiveChainstate();
      27                 :           4 :     auto sync_index = [&](bool do_flush, int expected_sync_height, int expected_commit_height) {
      28         [ +  - ]:           3 :         CoinStatsIndex index{interfaces::MakeChain(m_node), /*n_cache_size=*/1_MiB};
      29   [ +  -  +  -  :           6 :         BOOST_REQUIRE(index.Init());
             +  -  +  - ]
      30         [ +  - ]:           3 :         index.Sync();
      31         [ +  + ]:           3 :         if (do_flush) {
      32         [ +  - ]:           1 :             chainstate.ForceFlushStateToDisk();
      33   [ +  -  +  - ]:           1 :             m_node.chain->context()->validation_signals->SyncWithValidationInterfaceQueue();
      34                 :             :         }
      35   [ +  -  +  -  :           3 :         BOOST_CHECK_EQUAL(index.GetSummary().best_block_height, expected_sync_height);
                   +  - ]
      36         [ +  - ]:           3 :         index.Stop();
      37                 :             :         // Reload index to see which block data was actually committed.
      38   [ +  -  +  -  :           6 :         BOOST_REQUIRE(index.Init());
             +  -  +  - ]
      39   [ +  -  +  -  :           3 :         BOOST_CHECK_EQUAL(index.GetSummary().best_block_height, expected_commit_height);
                   +  - ]
      40         [ +  - ]:           3 :         index.Stop();
      41                 :           4 :     };
      42                 :             : 
      43                 :             :     // Part 1: Sync, then "crash" (stop without flushing). Models a node that
      44                 :             :     // started up, had its index catch up, but never flushed before going down.
      45                 :             :     // The end-of-sync Commit() runs at chain tip (height 100) but
      46                 :             :     // m_last_flushed_block is null, so it is skipped.
      47                 :           1 :     sync_index(false, 100, 0);
      48                 :             : 
      49                 :             :     // Part 2: Restart cleanly. Sync, force a chainstate flush, and drain the
      50                 :             :     // validation queue so the index's ChainStateFlushed callback runs.
      51                 :             :     // Now m_last_flushed_block == tip == 100 and the index can commit.
      52                 :           1 :     sync_index(true, 100, 100);
      53                 :             : 
      54                 :             :     // Part 3: Connect a new block on the chain without flushing
      55                 :             :     // (m_last_flushed_block stays at 100). For a real node this would happen
      56                 :             :     // in parallel with Sync(). Here we do it before Sync() to make the race
      57                 :             :     // state deterministic.
      58   [ +  -  +  - ]:           2 :     CreateAndProcessBlock({}, CScript() << OP_TRUE);
      59                 :           1 :     sync_index(false, 101, 100);
      60                 :           1 : }
      61                 :             : 
      62                 :             : BOOST_AUTO_TEST_SUITE_END()
        

Generated by: LCOV version 2.0-1