Line data Source code
1 : // Copyright (c) 2020-2021 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 1 : const CNetMsgMaker mm{0};
30 :
31 1 : peerman.InitializeNode(node, local_services);
32 1 : FlushSendBuffer(node); // Drop the version message added by InitializeNode.
33 :
34 1 : CSerializedNetMsg msg_version{
35 2 : mm.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 1 : CService{}, // dummy
41 1 : int64_t{}, // ignored service bits
42 1 : 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 : };
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 1 : 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{mm.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 1 : }
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 2 : }
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 3 : while (true) {
85 3 : const auto& [to_send, _more, _msg_type] = node.m_transport->GetBytesToSend(false);
86 3 : if (to_send.empty()) break;
87 0 : node.m_transport->MarkBytesSent(to_send.size());
88 : }
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 5 : while (true) {
97 5 : const auto& [to_send, _more, _msg_type] = node.m_transport->GetBytesToSend(false);
98 5 : if (to_send.empty()) break;
99 6 : NodeReceiveMsgBytes(node, to_send, complete);
100 6 : node.m_transport->MarkBytesSent(to_send.size());
101 : }
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));
111 0 : node->fSuccessfullyConnected = true;
112 0 : AddTestNode(*node);
113 0 : return node;
114 10 : }
115 :
116 1624 : std::vector<NodeEvictionCandidate> GetRandomNodeEvictionCandidates(int n_candidates, FastRandomContext& random_context)
117 : {
118 1624 : std::vector<NodeEvictionCandidate> candidates;
119 161042 : for (int id = 0; id < n_candidates; ++id) {
120 318836 : candidates.push_back({
121 159418 : /*id=*/id,
122 159418 : /*m_connected=*/std::chrono::seconds{random_context.randrange(100)},
123 159418 : /*m_min_ping_time=*/std::chrono::microseconds{random_context.randrange(100)},
124 159418 : /*m_last_block_time=*/std::chrono::seconds{random_context.randrange(100)},
125 159418 : /*m_last_tx_time=*/std::chrono::seconds{random_context.randrange(100)},
126 159418 : /*fRelevantServices=*/random_context.randbool(),
127 159418 : /*m_relay_txs=*/random_context.randbool(),
128 159418 : /*fBloomFilter=*/random_context.randbool(),
129 159418 : /*nKeyedNetGroup=*/random_context.randrange(100),
130 159418 : /*prefer_evict=*/random_context.randbool(),
131 159418 : /*m_is_local=*/random_context.randbool(),
132 159418 : /*m_network=*/ALL_NETWORKS[random_context.randrange(ALL_NETWORKS.size())],
133 : /*m_noban=*/false,
134 : /*m_conn_type=*/ConnectionType::INBOUND,
135 : });
136 159418 : }
137 1624 : return candidates;
138 1624 : }
|