LCOV - code coverage report
Current view: top level - src/test - net_peer_connection_tests.cpp (source / functions) Coverage Total Hit
Test: test_bitcoin_coverage.info Lines: 93.8 % 81 76
Test Date: 2024-08-28 04:44:32 Functions: 100.0 % 5 5
Branches: 52.8 % 354 187

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2023-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 <chainparams.h>
       6                 :             : #include <compat/compat.h>
       7                 :             : #include <net.h>
       8                 :             : #include <net_processing.h>
       9                 :             : #include <netaddress.h>
      10                 :             : #include <netbase.h>
      11                 :             : #include <netgroup.h>
      12                 :             : #include <node/connection_types.h>
      13                 :             : #include <node/protocol_version.h>
      14                 :             : #include <protocol.h>
      15                 :             : #include <random.h>
      16                 :             : #include <test/util/logging.h>
      17                 :             : #include <test/util/net.h>
      18                 :             : #include <test/util/random.h>
      19                 :             : #include <test/util/setup_common.h>
      20                 :             : #include <tinyformat.h>
      21                 :             : #include <util/chaintype.h>
      22                 :             : 
      23                 :             : #include <algorithm>
      24                 :             : #include <cstdint>
      25                 :             : #include <memory>
      26                 :             : #include <optional>
      27                 :             : #include <string>
      28                 :             : #include <vector>
      29                 :             : 
      30                 :             : #include <boost/test/unit_test.hpp>
      31                 :             : 
      32                 :           2 : struct LogIPsTestingSetup : public TestingSetup {
      33                 :           1 :     LogIPsTestingSetup()
      34         [ +  - ]:           2 :         : TestingSetup{ChainType::MAIN, {.extra_args = {"-logips"}}} {}
      35                 :             : };
      36                 :             : 
      37                 :             : BOOST_FIXTURE_TEST_SUITE(net_peer_connection_tests, LogIPsTestingSetup)
      38                 :             : 
      39                 :           4 : static CService ip(uint32_t i)
      40                 :             : {
      41                 :           4 :     struct in_addr s;
      42                 :           4 :     s.s_addr = i;
      43   [ +  -  +  - ]:           8 :     return CService{CNetAddr{s}, Params().GetDefaultPort()};
      44                 :             : }
      45                 :             : 
      46                 :             : /** Create a peer and connect to it. If the optional `address` (IP/CJDNS only) isn't passed, a random address is created. */
      47                 :           6 : static void AddPeer(NodeId& id, std::vector<CNode*>& nodes, PeerManager& peerman, ConnmanTestMsg& connman, ConnectionType conn_type, bool onion_peer = false, std::optional<std::string> address = std::nullopt)
      48                 :             : {
      49                 :           6 :     CAddress addr{};
      50                 :             : 
      51         [ +  + ]:           6 :     if (address.has_value()) {
      52   [ +  -  +  -  :           2 :         addr = CAddress{MaybeFlipIPv6toCJDNS(LookupNumeric(address.value(), Params().GetDefaultPort())), NODE_NONE};
          +  -  +  -  +  
                      - ]
      53         [ +  + ]:           4 :     } else if (onion_peer) {
      54                 :           1 :         auto tor_addr{g_insecure_rand_ctx.randbytes(ADDR_TORV3_SIZE)};
      55   [ +  -  +  -  :           2 :         BOOST_REQUIRE(addr.SetSpecial(OnionToString(tor_addr)));
             +  -  +  - ]
      56                 :           1 :     }
      57                 :             : 
      58   [ +  -  +  +  :          10 :     while (!addr.IsLocal() && !addr.IsRoutable()) {
             +  -  +  + ]
      59         [ +  - ]:           4 :         addr = CAddress{ip(g_insecure_rand_ctx.randbits(32)), NODE_NONE};
      60                 :             :     }
      61                 :             : 
      62   [ +  -  +  -  :          12 :     BOOST_REQUIRE(addr.IsValid());
             +  -  +  - ]
      63                 :             : 
      64                 :           6 :     const bool inbound_onion{onion_peer && conn_type == ConnectionType::INBOUND};
      65                 :             : 
      66   [ +  -  -  - ]:           6 :     nodes.emplace_back(new CNode{++id,
      67                 :             :                                  /*sock=*/nullptr,
      68                 :             :                                  addr,
      69                 :             :                                  /*nKeyedNetGroupIn=*/0,
      70                 :             :                                  /*nLocalHostNonceIn=*/0,
      71   [ +  -  -  + ]:          12 :                                  CAddress{},
      72                 :             :                                  /*addrNameIn=*/"",
      73                 :             :                                  conn_type,
      74   [ +  -  +  -  :          12 :                                  /*inbound_onion=*/inbound_onion});
                   +  - ]
      75                 :           6 :     CNode& node = *nodes.back();
      76                 :           6 :     node.SetCommonVersion(PROTOCOL_VERSION);
      77                 :             : 
      78         [ +  - ]:           6 :     peerman.InitializeNode(node, ServiceFlags(NODE_NETWORK | NODE_WITNESS));
      79         [ +  - ]:           6 :     node.fSuccessfullyConnected = true;
      80                 :             : 
      81         [ +  - ]:           6 :     connman.AddTestNode(node);
      82         [ +  - ]:          12 : }
      83                 :             : 
      84   [ +  -  +  -  :           7 : BOOST_AUTO_TEST_CASE(test_addnode_getaddednodeinfo_and_connection_detection)
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
      85                 :             : {
      86                 :           1 :     auto connman = std::make_unique<ConnmanTestMsg>(0x1337, 0x1337, *m_node.addrman, *m_node.netgroupman, Params());
      87         [ +  - ]:           1 :     auto peerman = PeerManager::make(*connman, *m_node.addrman, nullptr, *m_node.chainman, *m_node.mempool, *m_node.warnings, {});
      88                 :           1 :     NodeId id{0};
      89                 :           1 :     std::vector<CNode*> nodes;
      90                 :             : 
      91                 :             :     // Connect a localhost peer.
      92                 :           1 :     {
      93   [ +  -  +  - ]:           2 :         ASSERT_DEBUG_LOG("Added connection to 127.0.0.1:8333 peer=1");
      94   [ +  -  +  - ]:           1 :         AddPeer(id, nodes, *peerman, *connman, ConnectionType::MANUAL, /*onion_peer=*/false, /*address=*/"127.0.0.1");
      95   [ +  -  +  - ]:           2 :         BOOST_REQUIRE(nodes.back() != nullptr);
      96                 :           0 :     }
      97                 :             : 
      98                 :             :     // Call ConnectNode(), which is also called by RPC addnode onetry, for a localhost
      99                 :             :     // address that resolves to multiple IPs, including that of the connected peer.
     100                 :             :     // The connection attempt should consistently fail due to the check in ConnectNode().
     101         [ +  + ]:          11 :     for (int i = 0; i < 10; ++i) {
     102   [ +  -  +  - ]:          20 :         ASSERT_DEBUG_LOG("Not opening a connection to localhost, already connected to 127.0.0.1:8333");
     103   [ +  -  +  -  :          20 :         BOOST_CHECK(!connman->ConnectNodePublic(*peerman, "localhost", ConnectionType::MANUAL));
                   +  - ]
     104                 :          10 :     }
     105                 :             : 
     106                 :             :     // Add 3 more peer connections.
     107         [ +  - ]:           1 :     AddPeer(id, nodes, *peerman, *connman, ConnectionType::OUTBOUND_FULL_RELAY);
     108         [ +  - ]:           1 :     AddPeer(id, nodes, *peerman, *connman, ConnectionType::BLOCK_RELAY, /*onion_peer=*/true);
     109         [ +  - ]:           1 :     AddPeer(id, nodes, *peerman, *connman, ConnectionType::INBOUND);
     110                 :             : 
     111                 :             :     // Add a CJDNS peer connection.
     112   [ +  -  +  - ]:           1 :     AddPeer(id, nodes, *peerman, *connman, ConnectionType::INBOUND, /*onion_peer=*/false,
     113                 :             :             /*address=*/"[fc00:3344:5566:7788:9900:aabb:ccdd:eeff]:1234");
     114   [ +  -  +  -  :           2 :     BOOST_CHECK(nodes.back()->IsInboundConn());
                   +  - ]
     115   [ +  -  +  -  :           1 :     BOOST_CHECK_EQUAL(nodes.back()->ConnectedThroughNetwork(), Network::NET_CJDNS);
                   +  - ]
     116                 :             : 
     117   [ +  -  +  -  :           1 :     BOOST_TEST_MESSAGE("Call AddNode() for all the peers");
                   +  - ]
     118   [ +  -  +  + ]:           6 :     for (auto node : connman->TestNodes()) {
     119   [ +  -  +  -  :          10 :         BOOST_CHECK(connman->AddNode({/*m_added_node=*/node->addr.ToStringAddrPort(), /*m_use_v2transport=*/true}));
          +  -  +  -  +  
                      - ]
     120   [ +  -  +  -  :           5 :         BOOST_TEST_MESSAGE(strprintf("peer id=%s addr=%s", node->GetId(), node->addr.ToStringAddrPort()));
          +  -  +  -  +  
                      - ]
     121                 :           0 :     }
     122                 :             : 
     123   [ +  -  +  -  :           1 :     BOOST_TEST_MESSAGE("\nCall AddNode() with 2 addrs resolving to existing localhost addnode entry; neither should be added");
                   +  - ]
     124   [ +  -  +  -  :           2 :     BOOST_CHECK(!connman->AddNode({/*m_added_node=*/"127.0.0.1", /*m_use_v2transport=*/true}));
          +  -  +  -  +  
                      - ]
     125                 :             :     // OpenBSD doesn't support the IPv4 shorthand notation with omitted zero-bytes.
     126                 :             : #if !defined(__OpenBSD__)
     127   [ +  -  +  -  :           2 :     BOOST_CHECK(!connman->AddNode({/*m_added_node=*/"127.1", /*m_use_v2transport=*/true}));
          +  -  +  -  +  
                      - ]
     128                 :             : #endif
     129                 :             : 
     130   [ +  -  +  -  :           1 :     BOOST_TEST_MESSAGE("\nExpect GetAddedNodeInfo to return expected number of peers with `include_connected` true/false");
                   +  - ]
     131   [ +  -  +  -  :           1 :     BOOST_CHECK_EQUAL(connman->GetAddedNodeInfo(/*include_connected=*/true).size(), nodes.size());
                   +  - ]
     132   [ +  -  +  -  :           2 :     BOOST_CHECK(connman->GetAddedNodeInfo(/*include_connected=*/false).empty());
             +  -  +  - ]
     133                 :             : 
     134                 :             :     // Test AddedNodesContain()
     135   [ +  -  +  + ]:           6 :     for (auto node : connman->TestNodes()) {
     136   [ +  -  +  -  :          10 :         BOOST_CHECK(connman->AddedNodesContain(node->addr));
                   +  - ]
     137                 :           0 :     }
     138         [ +  - ]:           1 :     AddPeer(id, nodes, *peerman, *connman, ConnectionType::OUTBOUND_FULL_RELAY);
     139   [ +  -  +  -  :           2 :     BOOST_CHECK(!connman->AddedNodesContain(nodes.back()->addr));
             +  -  +  - ]
     140                 :             : 
     141   [ +  -  +  -  :           1 :     BOOST_TEST_MESSAGE("\nPrint GetAddedNodeInfo contents:");
                   +  - ]
     142   [ +  -  +  + ]:           6 :     for (const auto& info : connman->GetAddedNodeInfo(/*include_connected=*/true)) {
     143   [ +  -  +  -  :           5 :         BOOST_TEST_MESSAGE(strprintf("\nadded node: %s", info.m_params.m_added_node));
             +  -  +  - ]
     144   [ +  -  +  -  :           5 :         BOOST_TEST_MESSAGE(strprintf("connected: %s", info.fConnected));
             +  -  +  - ]
     145         [ +  - ]:           5 :         if (info.fConnected) {
     146   [ +  -  +  -  :           5 :             BOOST_TEST_MESSAGE(strprintf("IP address: %s", info.resolvedAddress.ToStringAddrPort()));
          +  -  +  -  +  
                      - ]
     147   [ +  -  +  -  :           8 :             BOOST_TEST_MESSAGE(strprintf("direction: %s", info.fInbound ? "inbound" : "outbound"));
          +  +  +  -  +  
                      - ]
     148                 :             :         }
     149                 :           1 :     }
     150                 :             : 
     151   [ +  -  +  -  :           1 :     BOOST_TEST_MESSAGE("\nCheck that all connected peers are correctly detected as connected");
                   +  - ]
     152   [ +  -  +  + ]:           7 :     for (auto node : connman->TestNodes()) {
     153   [ +  -  +  -  :          12 :         BOOST_CHECK(connman->AlreadyConnectedPublic(node->addr));
                   +  - ]
     154                 :           0 :     }
     155                 :             : 
     156                 :             :     // Clean up
     157   [ +  -  +  + ]:           7 :     for (auto node : connman->TestNodes()) {
     158         [ +  - ]:           6 :         peerman->FinalizeNode(*node);
     159                 :           0 :     }
     160         [ +  - ]:           1 :     connman->ClearTestNodes();
     161   [ +  -  +  -  :          10 : }
          +  -  +  -  +  
                      - ]
     162                 :             : 
     163                 :             : BOOST_AUTO_TEST_SUITE_END()
        

Generated by: LCOV version 2.0-1