peerman_tests.cpp
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 static void mineBlock(const node::NodeContext& node, std::chrono::seconds block_time) 20 { 21 auto curr_time = GetTime<std::chrono::seconds>(); 22 SetMockTime(block_time); // update time so the block is created with it 23 CBlock block = node::BlockAssembler{node.chainman->ActiveChainstate(), nullptr}.CreateNewBlock(CScript() << OP_TRUE)->block; 24 while (!CheckProofOfWork(block.GetHash(), block.nBits, node.chainman->GetConsensus())) ++block.nNonce; 25 block.fChecked = true; // little speedup 26 SetMockTime(curr_time); // process block at current time 27 Assert(node.chainman->ProcessNewBlock(std::make_shared<const CBlock>(block), /*force_processing=*/true, /*min_pow_checked=*/true, nullptr)); 28 node.validation_signals->SyncWithValidationInterfaceQueue(); // drain events queue 29 } 30 31 // Verifying when network-limited peer connections are desirable based on the node's proximity to the tip 32 BOOST_AUTO_TEST_CASE(connections_desirable_service_flags) 33 { 34 std::unique_ptr<PeerManager> peerman = PeerManager::make(*m_node.connman, *m_node.addrman, nullptr, *m_node.chainman, *m_node.mempool, {}); 35 auto consensus = m_node.chainman->GetParams().GetConsensus(); 36 37 // Check we start connecting to full nodes 38 ServiceFlags peer_flags{NODE_WITNESS | NODE_NETWORK_LIMITED}; 39 BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK | NODE_WITNESS)); 40 41 // Make peerman aware of the initial best block and verify we accept limited peers when we start close to the tip time. 42 auto tip = WITH_LOCK(::cs_main, return m_node.chainman->ActiveChain().Tip()); 43 uint64_t tip_block_time = tip->GetBlockTime(); 44 int tip_block_height = tip->nHeight; 45 peerman->SetBestBlock(tip_block_height, std::chrono::seconds{tip_block_time}); 46 47 SetMockTime(tip_block_time + 1); // Set node time to tip time 48 BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS)); 49 50 // Check we don't disallow limited peers connections when we are behind but still recoverable (below the connection safety window) 51 SetMockTime(GetTime<std::chrono::seconds>() + std::chrono::seconds{consensus.nPowTargetSpacing * (NODE_NETWORK_LIMITED_ALLOW_CONN_BLOCKS - 1)}); 52 BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS)); 53 54 // Check we disallow limited peers connections when we are further than the limited peers safety window 55 SetMockTime(GetTime<std::chrono::seconds>() + std::chrono::seconds{consensus.nPowTargetSpacing * 2}); 56 BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK | NODE_WITNESS)); 57 58 // By now, we tested that the connections desirable services flags change based on the node's time proximity to the tip. 59 // Now, perform the same tests for when the node receives a block. 60 m_node.validation_signals->RegisterValidationInterface(peerman.get()); 61 62 // First, verify a block in the past doesn't enable limited peers connections 63 // At this point, our time is (NODE_NETWORK_LIMITED_ALLOW_CONN_BLOCKS + 1) * 10 minutes ahead the tip's time. 64 mineBlock(m_node, /*block_time=*/std::chrono::seconds{tip_block_time + 1}); 65 BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK | NODE_WITNESS)); 66 67 // Verify a block close to the tip enables limited peers connections 68 mineBlock(m_node, /*block_time=*/GetTime<std::chrono::seconds>()); 69 BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS)); 70 71 // Lastly, verify the stale tip checks can disallow limited peers connections after not receiving blocks for a prolonged period. 72 SetMockTime(GetTime<std::chrono::seconds>() + std::chrono::seconds{consensus.nPowTargetSpacing * NODE_NETWORK_LIMITED_ALLOW_CONN_BLOCKS + 1}); 73 BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK | NODE_WITNESS)); 74 } 75 76 BOOST_AUTO_TEST_SUITE_END()