Bitcoin Core  27.99.0
P2P Digital Currency
net.cpp
Go to the documentation of this file.
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 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  auto& peerman{static_cast<PeerManager&>(*m_msgproc)};
28  auto& connman{*this};
29 
30  peerman.InitializeNode(node, local_services);
31  FlushSendBuffer(node); // Drop the version message added by InitializeNode.
32 
33  CSerializedNetMsg msg_version{
35  version, //
36  Using<CustomUintFormatter<8>>(remote_services), //
37  int64_t{}, // dummy time
38  int64_t{}, // ignored service bits
39  CNetAddr::V1(CService{}), // dummy
40  int64_t{}, // ignored service bits
41  CNetAddr::V1(CService{}), // ignored
42  uint64_t{1}, // dummy nonce
43  std::string{}, // dummy subver
44  int32_t{}, // dummy starting_height
45  relay_txs),
46  };
47 
48  (void)connman.ReceiveMsgFrom(node, std::move(msg_version));
49  node.fPauseSend = false;
50  connman.ProcessMessagesOnce(node);
51  peerman.SendMessages(&node);
52  FlushSendBuffer(node); // Drop the verack message added by SendMessages.
53  if (node.fDisconnect) return;
54  assert(node.nVersion == version);
55  assert(node.GetCommonVersion() == std::min(version, PROTOCOL_VERSION));
56  CNodeStateStats statestats;
57  assert(peerman.GetNodeStateStats(node.GetId(), statestats));
58  assert(statestats.m_relay_txs == (relay_txs && !node.IsBlockOnlyConn()));
59  assert(statestats.their_services == remote_services);
60  if (successfully_connected) {
62  (void)connman.ReceiveMsgFrom(node, std::move(msg_verack));
63  node.fPauseSend = false;
64  connman.ProcessMessagesOnce(node);
65  peerman.SendMessages(&node);
66  assert(node.fSuccessfullyConnected == true);
67  }
68 }
69 
70 void ConnmanTestMsg::NodeReceiveMsgBytes(CNode& node, Span<const uint8_t> msg_bytes, bool& complete) const
71 {
72  assert(node.ReceiveMsgBytes(msg_bytes, complete));
73  if (complete) {
74  node.MarkReceivedMsgsForProcessing();
75  }
76 }
77 
79 {
80  LOCK(node.cs_vSend);
81  node.vSendMsg.clear();
82  node.m_send_memusage = 0;
83  while (true) {
84  const auto& [to_send, _more, _msg_type] = node.m_transport->GetBytesToSend(false);
85  if (to_send.empty()) break;
86  node.m_transport->MarkBytesSent(to_send.size());
87  }
88 }
89 
91 {
92  bool queued = node.m_transport->SetMessageToSend(ser_msg);
93  assert(queued);
94  bool complete{false};
95  while (true) {
96  const auto& [to_send, _more, _msg_type] = node.m_transport->GetBytesToSend(false);
97  if (to_send.empty()) break;
98  NodeReceiveMsgBytes(node, to_send, complete);
99  node.m_transport->MarkBytesSent(to_send.size());
100  }
101  return complete;
102 }
103 
104 CNode* ConnmanTestMsg::ConnectNodePublic(PeerManager& peerman, const char* pszDest, ConnectionType conn_type)
105 {
106  CNode* node = ConnectNode(CAddress{}, pszDest, /*fCountFailure=*/false, conn_type, /*use_v2transport=*/true);
107  if (!node) return nullptr;
108  node->SetCommonVersion(PROTOCOL_VERSION);
110  node->fSuccessfullyConnected = true;
111  AddTestNode(*node);
112  return node;
113 }
114 
115 std::vector<NodeEvictionCandidate> GetRandomNodeEvictionCandidates(int n_candidates, FastRandomContext& random_context)
116 {
117  std::vector<NodeEvictionCandidate> candidates;
118  candidates.reserve(n_candidates);
119  for (int id = 0; id < n_candidates; ++id) {
120  candidates.push_back({
121  /*id=*/id,
122  /*m_connected=*/std::chrono::seconds{random_context.randrange(100)},
123  /*m_min_ping_time=*/std::chrono::microseconds{random_context.randrange(100)},
124  /*m_last_block_time=*/std::chrono::seconds{random_context.randrange(100)},
125  /*m_last_tx_time=*/std::chrono::seconds{random_context.randrange(100)},
126  /*fRelevantServices=*/random_context.randbool(),
127  /*m_relay_txs=*/random_context.randbool(),
128  /*fBloomFilter=*/random_context.randbool(),
129  /*nKeyedNetGroup=*/random_context.randrange(100),
130  /*prefer_evict=*/random_context.randbool(),
131  /*m_is_local=*/random_context.randbool(),
132  /*m_network=*/ALL_NETWORKS[random_context.randrange(ALL_NETWORKS.size())],
133  /*m_noban=*/false,
134  /*m_conn_type=*/ConnectionType::INBOUND,
135  });
136  }
137  return candidates;
138 }
A CService with information about it as peer.
Definition: protocol.h:332
CNode * ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type, bool use_v2transport) EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex)
Definition: net.cpp:389
static constexpr SerParams V1
Definition: netaddress.h:231
Information about a peer.
Definition: net.h:672
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:531
Fast randomness source.
Definition: random.h:145
bool randbool() noexcept
Generate a random boolean.
Definition: random.h:228
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
Definition: random.h:203
virtual void InitializeNode(CNode &node, ServiceFlags our_services)=0
Initialize a peer (setup state, queue any initial messages)
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:98
ConnectionType
Different types of connections to a peer.
@ INBOUND
Inbound connections are those initiated by a peer.
CSerializedNetMsg Make(std::string msg_type, Args &&... args)
const char * VERSION
The version message provides information about the transmitting node to the receiving node at the beg...
Definition: protocol.cpp:13
const char * VERACK
The verack message acknowledges a previously-received version message, informing the connecting node ...
Definition: protocol.cpp:14
Definition: init.h:25
ServiceFlags
nServices flags
Definition: protocol.h:274
@ NODE_WITNESS
Definition: protocol.h:285
@ NODE_NETWORK
Definition: protocol.h:280
static const int PROTOCOL_VERSION
network protocol versioning
static Wrapper< Formatter, T & > Using(T &&t)
Cause serialization/deserialization of an object to be done using a specified formatter class.
Definition: serialize.h:510
ServiceFlags their_services
bool ReceiveMsgFrom(CNode &node, CSerializedNetMsg &&ser_msg) const
Definition: net.cpp:90
CNode * ConnectNodePublic(PeerManager &peerman, const char *pszDest, ConnectionType conn_type) EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex)
Definition: net.cpp:104
void NodeReceiveMsgBytes(CNode &node, Span< const uint8_t > msg_bytes, bool &complete) const
Definition: net.cpp:70
void AddTestNode(CNode &node)
Definition: net.h:48
void FlushSendBuffer(CNode &node) const
Definition: net.cpp:78
Serialization wrapper class for custom integers and enums.
Definition: serialize.h:543
#define LOCK(cs)
Definition: sync.h:257
std::vector< NodeEvictionCandidate > GetRandomNodeEvictionCandidates(int n_candidates, FastRandomContext &random_context)
Definition: net.cpp:115
constexpr auto ALL_NETWORKS
Definition: net.h:121
assert(!tx.IsCoinBase())