LCOV - code coverage report
Current view: top level - src/test - peerman_tests.cpp (source / functions) Coverage Total Hit
Test: test_bitcoin_coverage.info Lines: 100.0 % 34 34
Test Date: 2024-08-28 04:44:32 Functions: 100.0 % 4 4
Branches: 50.0 % 154 77

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2024-present The Bitcoin Core developers
       2                 :             : // Distributed under the MIT software license, see the accompanying
       3                 :             : // file COPYING or https://www.opensource.org/licenses/mit-license.php.
       4                 :             : 
       5                 :             : #include <chainparams.h>
       6                 :             : #include <node/miner.h>
       7                 :             : #include <net_processing.h>
       8                 :             : #include <pow.h>
       9                 :             : #include <test/util/setup_common.h>
      10                 :             : #include <validation.h>
      11                 :             : 
      12                 :             : #include <boost/test/unit_test.hpp>
      13                 :             : 
      14                 :             : BOOST_FIXTURE_TEST_SUITE(peerman_tests, RegTestingSetup)
      15                 :             : 
      16                 :             : /** Window, in blocks, for connecting to NODE_NETWORK_LIMITED peers */
      17                 :             : static constexpr int64_t NODE_NETWORK_LIMITED_ALLOW_CONN_BLOCKS = 144;
      18                 :             : 
      19                 :           2 : static void mineBlock(const node::NodeContext& node, std::chrono::seconds block_time)
      20                 :             : {
      21                 :           2 :     auto curr_time = GetTime<std::chrono::seconds>();
      22                 :           2 :     SetMockTime(block_time); // update time so the block is created with it
      23                 :           2 :     node::BlockAssembler::Options options;
      24   [ +  -  +  -  :           2 :     CBlock block = node::BlockAssembler{node.chainman->ActiveChainstate(), nullptr, options}.CreateNewBlock(CScript() << OP_TRUE)->block;
                   +  - ]
      25   [ +  -  +  -  :           2 :     while (!CheckProofOfWork(block.GetHash(), block.nBits, node.chainman->GetConsensus())) ++block.nNonce;
                   -  + ]
      26                 :           2 :     block.fChecked = true; // little speedup
      27         [ +  - ]:           2 :     SetMockTime(curr_time); // process block at current time
      28   [ +  -  +  -  :           2 :     Assert(node.chainman->ProcessNewBlock(std::make_shared<const CBlock>(block), /*force_processing=*/true, /*min_pow_checked=*/true, nullptr));
                   +  - ]
      29         [ +  - ]:           2 :     node.validation_signals->SyncWithValidationInterfaceQueue(); // drain events queue
      30                 :           2 : }
      31                 :             : 
      32                 :             : // Verifying when network-limited peer connections are desirable based on the node's proximity to the tip
      33   [ +  -  +  -  :           7 : BOOST_AUTO_TEST_CASE(connections_desirable_service_flags)
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
      34                 :             : {
      35                 :           1 :     std::unique_ptr<PeerManager> peerman = PeerManager::make(*m_node.connman, *m_node.addrman, nullptr, *m_node.chainman, *m_node.mempool, *m_node.warnings, {});
      36         [ +  - ]:           1 :     auto consensus = m_node.chainman->GetParams().GetConsensus();
      37                 :             : 
      38                 :             :     // Check we start connecting to full nodes
      39                 :           1 :     ServiceFlags peer_flags{NODE_WITNESS | NODE_NETWORK_LIMITED};
      40   [ +  -  +  -  :           2 :     BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK | NODE_WITNESS));
             +  -  +  - ]
      41                 :             : 
      42                 :             :     // Make peerman aware of the initial best block and verify we accept limited peers when we start close to the tip time.
      43   [ +  -  +  -  :           4 :     auto tip = WITH_LOCK(::cs_main, return m_node.chainman->ActiveChain().Tip());
                   +  - ]
      44         [ +  - ]:           1 :     uint64_t tip_block_time = tip->GetBlockTime();
      45                 :           1 :     int tip_block_height = tip->nHeight;
      46         [ +  - ]:           1 :     peerman->SetBestBlock(tip_block_height, std::chrono::seconds{tip_block_time});
      47                 :             : 
      48         [ +  - ]:           1 :     SetMockTime(tip_block_time + 1); // Set node time to tip time
      49   [ +  -  +  -  :           2 :     BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS));
                   +  - ]
      50                 :             : 
      51                 :             :     // Check we don't disallow limited peers connections when we are behind but still recoverable (below the connection safety window)
      52         [ +  - ]:           1 :     SetMockTime(GetTime<std::chrono::seconds>() + std::chrono::seconds{consensus.nPowTargetSpacing * (NODE_NETWORK_LIMITED_ALLOW_CONN_BLOCKS - 1)});
      53   [ +  -  +  -  :           2 :     BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS));
                   +  - ]
      54                 :             : 
      55                 :             :     // Check we disallow limited peers connections when we are further than the limited peers safety window
      56         [ +  - ]:           1 :     SetMockTime(GetTime<std::chrono::seconds>() + std::chrono::seconds{consensus.nPowTargetSpacing * 2});
      57   [ +  -  +  -  :           2 :     BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK | NODE_WITNESS));
             +  -  +  - ]
      58                 :             : 
      59                 :             :     // By now, we tested that the connections desirable services flags change based on the node's time proximity to the tip.
      60                 :             :     // Now, perform the same tests for when the node receives a block.
      61         [ +  - ]:           1 :     m_node.validation_signals->RegisterValidationInterface(peerman.get());
      62                 :             : 
      63                 :             :     // First, verify a block in the past doesn't enable limited peers connections
      64                 :             :     // At this point, our time is (NODE_NETWORK_LIMITED_ALLOW_CONN_BLOCKS + 1) * 10 minutes ahead the tip's time.
      65         [ +  - ]:           1 :     mineBlock(m_node, /*block_time=*/std::chrono::seconds{tip_block_time + 1});
      66   [ +  -  +  -  :           2 :     BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK | NODE_WITNESS));
                   +  - ]
      67                 :             : 
      68                 :             :     // Verify a block close to the tip enables limited peers connections
      69         [ +  - ]:           1 :     mineBlock(m_node, /*block_time=*/GetTime<std::chrono::seconds>());
      70   [ +  -  +  -  :           2 :     BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS));
                   +  - ]
      71                 :             : 
      72                 :             :     // Lastly, verify the stale tip checks can disallow limited peers connections after not receiving blocks for a prolonged period.
      73         [ +  - ]:           1 :     SetMockTime(GetTime<std::chrono::seconds>() + std::chrono::seconds{consensus.nPowTargetSpacing * NODE_NETWORK_LIMITED_ALLOW_CONN_BLOCKS + 1});
      74   [ +  -  +  -  :           2 :     BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK | NODE_WITNESS));
                   +  - ]
      75                 :           1 : }
      76                 :             : 
      77                 :             : BOOST_AUTO_TEST_SUITE_END()
        

Generated by: LCOV version 2.0-1