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