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 <test/util/net.h>
6 : :
7 : : #include <net.h>
8 : : #include <net_processing.h>
9 : : #include <netaddress.h>
10 : : #include <netmessagemaker.h>
11 : : #include <node/connection_types.h>
12 : : #include <node/eviction.h>
13 : : #include <protocol.h>
14 : : #include <random.h>
15 : : #include <serialize.h>
16 : : #include <span.h>
17 : :
18 : : #include <vector>
19 : :
20 : 0 : void ConnmanTestMsg::Handshake(CNode& node,
21 : : bool successfully_connected,
22 : : ServiceFlags remote_services,
23 : : ServiceFlags local_services,
24 : : int32_t version,
25 : : bool relay_txs)
26 : : {
27 : 0 : auto& peerman{static_cast<PeerManager&>(*m_msgproc)};
28 : 0 : auto& connman{*this};
29 : :
30 : 0 : peerman.InitializeNode(node, local_services);
31 : 0 : FlushSendBuffer(node); // Drop the version message added by InitializeNode.
32 : :
33 : 0 : CSerializedNetMsg msg_version{
34 [ # # ][ # # ]: 0 : NetMsg::Make(NetMsgType::VERSION,
35 : : version, //
36 [ # # ]: 0 : Using<CustomUintFormatter<8>>(remote_services), //
37 : 0 : int64_t{}, // dummy time
38 : 0 : int64_t{}, // ignored service bits
39 [ # # ][ # # ]: 0 : CNetAddr::V1(CService{}), // dummy
40 : 0 : int64_t{}, // ignored service bits
41 [ # # ][ # # ]: 0 : CNetAddr::V1(CService{}), // ignored
42 : 0 : uint64_t{1}, // dummy nonce
43 : 0 : std::string{}, // dummy subver
44 : 0 : int32_t{}, // dummy starting_height
45 : : relay_txs),
46 : : };
47 : :
48 [ # # ]: 0 : (void)connman.ReceiveMsgFrom(node, std::move(msg_version));
49 : 0 : node.fPauseSend = false;
50 [ # # ]: 0 : connman.ProcessMessagesOnce(node);
51 [ # # ]: 0 : peerman.SendMessages(&node);
52 [ # # ]: 0 : FlushSendBuffer(node); // Drop the verack message added by SendMessages.
53 [ # # ]: 0 : if (node.fDisconnect) return;
54 [ # # ]: 0 : assert(node.nVersion == version);
55 [ # # ][ # # ]: 0 : assert(node.GetCommonVersion() == std::min(version, PROTOCOL_VERSION));
[ # # ]
56 : 0 : CNodeStateStats statestats;
57 [ # # ][ # # ]: 0 : assert(peerman.GetNodeStateStats(node.GetId(), statestats));
[ # # ]
58 [ # # ][ # # ]: 0 : assert(statestats.m_relay_txs == (relay_txs && !node.IsBlockOnlyConn()));
[ # # ]
59 [ # # ]: 0 : assert(statestats.their_services == remote_services);
60 [ # # ]: 0 : if (successfully_connected) {
61 [ # # ][ # # ]: 0 : CSerializedNetMsg msg_verack{NetMsg::Make(NetMsgType::VERACK)};
62 [ # # ]: 0 : (void)connman.ReceiveMsgFrom(node, std::move(msg_verack));
63 : 0 : node.fPauseSend = false;
64 [ # # ]: 0 : connman.ProcessMessagesOnce(node);
65 [ # # ]: 0 : peerman.SendMessages(&node);
66 [ # # ]: 0 : assert(node.fSuccessfullyConnected == true);
67 : 0 : }
68 [ # # ]: 0 : }
69 : :
70 : 0 : void ConnmanTestMsg::NodeReceiveMsgBytes(CNode& node, Span<const uint8_t> msg_bytes, bool& complete) const
71 : : {
72 [ # # ]: 0 : assert(node.ReceiveMsgBytes(msg_bytes, complete));
73 [ # # ]: 0 : if (complete) {
74 : 0 : node.MarkReceivedMsgsForProcessing();
75 : 0 : }
76 : 0 : }
77 : :
78 : 0 : void ConnmanTestMsg::FlushSendBuffer(CNode& node) const
79 : : {
80 : 0 : LOCK(node.cs_vSend);
81 : 0 : node.vSendMsg.clear();
82 : 0 : node.m_send_memusage = 0;
83 : 0 : while (true) {
84 : 0 : const auto& [to_send, _more, _msg_type] = node.m_transport->GetBytesToSend(false);
85 [ # # ]: 0 : if (to_send.empty()) break;
86 : 0 : node.m_transport->MarkBytesSent(to_send.size());
87 : : }
88 : 0 : }
89 : :
90 : 0 : bool ConnmanTestMsg::ReceiveMsgFrom(CNode& node, CSerializedNetMsg&& ser_msg) const
91 : : {
92 : 0 : bool queued = node.m_transport->SetMessageToSend(ser_msg);
93 [ # # ]: 0 : assert(queued);
94 : 0 : bool complete{false};
95 : 0 : while (true) {
96 : 0 : const auto& [to_send, _more, _msg_type] = node.m_transport->GetBytesToSend(false);
97 [ # # ]: 0 : if (to_send.empty()) break;
98 : 0 : NodeReceiveMsgBytes(node, to_send, complete);
99 : 0 : node.m_transport->MarkBytesSent(to_send.size());
100 : : }
101 : 0 : return complete;
102 : : }
103 : :
104 : 0 : CNode* ConnmanTestMsg::ConnectNodePublic(PeerManager& peerman, const char* pszDest, ConnectionType conn_type)
105 : : {
106 [ # # ]: 0 : CNode* node = ConnectNode(CAddress{}, pszDest, /*fCountFailure=*/false, conn_type, /*use_v2transport=*/true);
107 [ # # ]: 0 : if (!node) return nullptr;
108 : 0 : node->SetCommonVersion(PROTOCOL_VERSION);
109 : 0 : peerman.InitializeNode(*node, ServiceFlags(NODE_NETWORK | NODE_WITNESS));
110 : 0 : node->fSuccessfullyConnected = true;
111 : 0 : AddTestNode(*node);
112 : 0 : return node;
113 : 0 : }
114 : :
115 : 0 : std::vector<NodeEvictionCandidate> GetRandomNodeEvictionCandidates(int n_candidates, FastRandomContext& random_context)
116 : : {
117 : 0 : std::vector<NodeEvictionCandidate> candidates;
118 [ # # ]: 0 : candidates.reserve(n_candidates);
119 [ # # ]: 0 : for (int id = 0; id < n_candidates; ++id) {
120 [ # # ][ # # ]: 0 : candidates.push_back({
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
121 : 0 : /*id=*/id,
122 [ # # ]: 0 : /*m_connected=*/std::chrono::seconds{random_context.randrange(100)},
123 [ # # ]: 0 : /*m_min_ping_time=*/std::chrono::microseconds{random_context.randrange(100)},
124 [ # # ]: 0 : /*m_last_block_time=*/std::chrono::seconds{random_context.randrange(100)},
125 [ # # ]: 0 : /*m_last_tx_time=*/std::chrono::seconds{random_context.randrange(100)},
126 : 0 : /*fRelevantServices=*/random_context.randbool(),
127 : 0 : /*m_relay_txs=*/random_context.randbool(),
128 : 0 : /*fBloomFilter=*/random_context.randbool(),
129 : 0 : /*nKeyedNetGroup=*/random_context.randrange(100),
130 : 0 : /*prefer_evict=*/random_context.randbool(),
131 : 0 : /*m_is_local=*/random_context.randbool(),
132 : 0 : /*m_network=*/ALL_NETWORKS[random_context.randrange(ALL_NETWORKS.size())],
133 : : /*m_noban=*/false,
134 : : /*m_conn_type=*/ConnectionType::INBOUND,
135 : : });
136 : 0 : }
137 : 0 : return candidates;
138 [ # # ]: 0 : }
|