Bitcoin Core  31.0.0
P2P Digital Currency
denialofservice_tests.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-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 // Unit tests for denial-of-service detection/prevention code
6 
7 #include <banman.h>
8 #include <chainparams.h>
9 #include <common/args.h>
10 #include <net.h>
11 #include <net_processing.h>
12 #include <pubkey.h>
13 #include <script/sign.h>
14 #include <script/signingprovider.h>
15 #include <serialize.h>
16 #include <test/util/net.h>
17 #include <test/util/random.h>
18 #include <test/util/setup_common.h>
19 #include <util/string.h>
20 #include <util/time.h>
21 #include <validation.h>
22 
23 #include <array>
24 #include <cstdint>
25 
26 #include <boost/test/unit_test.hpp>
27 
28 static CService ip(uint32_t i)
29 {
30  struct in_addr s;
31  s.s_addr = i;
32  return CService(CNetAddr(s), Params().GetDefaultPort());
33 }
34 
35 BOOST_FIXTURE_TEST_SUITE(denialofservice_tests, TestingSetup)
36 
37 // Test eviction of an outbound peer whose chain never advances
38 // Mock a node connection, and use mocktime to simulate a peer
39 // which never sends any headers messages. PeerLogic should
40 // decide to evict that outbound peer, after the appropriate timeouts.
41 // Note that we protect 4 outbound nodes from being subject to
42 // this logic; this test takes advantage of that protection only
43 // being applied to nodes which send headers with sufficient
44 // work.
45 BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
46 {
48 
49  ConnmanTestMsg& connman = static_cast<ConnmanTestMsg&>(*m_node.connman);
50  // Disable inactivity checks for this test to avoid interference
51  connman.SetPeerConnectTimeout(99999s);
52  PeerManager& peerman = *m_node.peerman;
53 
54  // Mock an outbound peer
55  CAddress addr1(ip(0xa0b0c001), NODE_NONE);
56  NodeId id{0};
57  CNode dummyNode1{id++,
58  /*sock=*/nullptr,
59  addr1,
60  /*nKeyedNetGroupIn=*/0,
61  /*nLocalHostNonceIn=*/0,
62  CAddress(),
63  /*addrNameIn=*/"",
65  /*inbound_onion=*/false,
66  /*network_key=*/0};
67 
68  connman.Handshake(
69  /*node=*/dummyNode1,
70  /*successfully_connected=*/true,
71  /*remote_services=*/ServiceFlags(NODE_NETWORK | NODE_WITNESS),
72  /*local_services=*/ServiceFlags(NODE_NETWORK | NODE_WITNESS),
73  /*version=*/PROTOCOL_VERSION,
74  /*relay_txs=*/true);
75 
76  // This test requires that we have a chain with non-zero work.
77  {
78  LOCK(cs_main);
79  BOOST_CHECK(m_node.chainman->ActiveChain().Tip() != nullptr);
80  BOOST_CHECK(m_node.chainman->ActiveChain().Tip()->nChainWork > 0);
81  }
82 
83  // Test starts here
84  BOOST_CHECK(peerman.SendMessages(dummyNode1)); // should result in getheaders
85 
86  {
87  LOCK(dummyNode1.cs_vSend);
88  const auto& [to_send, _more, _msg_type] = dummyNode1.m_transport->GetBytesToSend(false);
89  BOOST_CHECK(!to_send.empty());
90  }
91  connman.FlushSendBuffer(dummyNode1);
92 
93  int64_t nStartTime = GetTime();
94  // Wait 21 minutes
95  SetMockTime(nStartTime+21*60);
96  BOOST_CHECK(peerman.SendMessages(dummyNode1)); // should result in getheaders
97  {
98  LOCK(dummyNode1.cs_vSend);
99  const auto& [to_send, _more, _msg_type] = dummyNode1.m_transport->GetBytesToSend(false);
100  BOOST_CHECK(!to_send.empty());
101  }
102  // Wait 3 more minutes
103  SetMockTime(nStartTime+24*60);
104  BOOST_CHECK(peerman.SendMessages(dummyNode1)); // should result in disconnect
105  BOOST_CHECK(dummyNode1.fDisconnect == true);
106 
107  peerman.FinalizeNode(dummyNode1);
108 }
109 
111 void AddRandomOutboundPeer(NodeId& id, std::vector<CNode*>& vNodes, PeerManager& peerLogic, ConnmanTestMsg& connman, ConnectionType connType, bool onion_peer = false)
112 {
113  CAddress addr;
114 
115  if (onion_peer) {
116  auto tor_addr{m_rng.randbytes(ADDR_TORV3_SIZE)};
117  BOOST_REQUIRE(addr.SetSpecial(OnionToString(tor_addr)));
118  }
119 
120  while (!addr.IsRoutable()) {
121  addr = CAddress(ip(m_rng.randbits(32)), NODE_NONE);
122  }
123 
124  vNodes.emplace_back(new CNode{id++,
125  /*sock=*/nullptr,
126  addr,
127  /*nKeyedNetGroupIn=*/0,
128  /*nLocalHostNonceIn=*/0,
129  CAddress(),
130  /*addrNameIn=*/"",
131  connType,
132  /*inbound_onion=*/false,
133  /*network_key=*/0});
134  CNode &node = *vNodes.back();
135  node.SetCommonVersion(PROTOCOL_VERSION);
136 
138  node.fSuccessfullyConnected = true;
139 
140  connman.AddTestNode(node);
141 }
142 }; // struct OutboundTest
143 
144 BOOST_FIXTURE_TEST_CASE(stale_tip_peer_management, OutboundTest)
145 {
146  NodeId id{0};
147  auto connman = std::make_unique<ConnmanTestMsg>(0x1337, 0x1337, *m_node.addrman, *m_node.netgroupman, Params());
148  auto peerLogic = PeerManager::make(*connman, *m_node.addrman, nullptr, *m_node.chainman, *m_node.mempool, *m_node.warnings, {});
149 
150  constexpr int max_outbound_full_relay = MAX_OUTBOUND_FULL_RELAY_CONNECTIONS;
151  CConnman::Options options;
153 
154  const auto time_init{GetTime<std::chrono::seconds>()};
155  SetMockTime(time_init);
156  const auto time_later{time_init + 3 * std::chrono::seconds{m_node.chainman->GetConsensus().nPowTargetSpacing} + 1s};
157  connman->Init(options);
158  std::vector<CNode *> vNodes;
159 
160  // Mock some outbound peers
161  for (int i = 0; i < max_outbound_full_relay; ++i) {
162  AddRandomOutboundPeer(id, vNodes, *peerLogic, *connman, ConnectionType::OUTBOUND_FULL_RELAY);
163  }
164 
165  peerLogic->CheckForStaleTipAndEvictPeers();
166 
167  // No nodes should be marked for disconnection while we have no extra peers
168  for (const CNode *node : vNodes) {
169  BOOST_CHECK(node->fDisconnect == false);
170  }
171 
172  SetMockTime(time_later);
173 
174  // Now tip should definitely be stale, and we should look for an extra
175  // outbound peer
176  peerLogic->CheckForStaleTipAndEvictPeers();
177  BOOST_CHECK(connman->GetTryNewOutboundPeer());
178 
179  // Still no peers should be marked for disconnection
180  for (const CNode *node : vNodes) {
181  BOOST_CHECK(node->fDisconnect == false);
182  }
183 
184  // If we add one more peer, something should get marked for eviction
185  // on the next check (since we're mocking the time to be in the future, the
186  // required time connected check should be satisfied).
187  SetMockTime(time_init);
188  AddRandomOutboundPeer(id, vNodes, *peerLogic, *connman, ConnectionType::OUTBOUND_FULL_RELAY);
189  SetMockTime(time_later);
190 
191  peerLogic->CheckForStaleTipAndEvictPeers();
192  for (int i = 0; i < max_outbound_full_relay; ++i) {
193  BOOST_CHECK(vNodes[i]->fDisconnect == false);
194  }
195  // Last added node should get marked for eviction
196  BOOST_CHECK(vNodes.back()->fDisconnect == true);
197 
198  vNodes.back()->fDisconnect = false;
199 
200  // Update the last announced block time for the last
201  // peer, and check that the next newest node gets evicted.
202  peerLogic->UpdateLastBlockAnnounceTime(vNodes.back()->GetId(), GetTime());
203 
204  peerLogic->CheckForStaleTipAndEvictPeers();
205  for (int i = 0; i < max_outbound_full_relay - 1; ++i) {
206  BOOST_CHECK(vNodes[i]->fDisconnect == false);
207  }
208  BOOST_CHECK(vNodes[max_outbound_full_relay-1]->fDisconnect == true);
209  BOOST_CHECK(vNodes.back()->fDisconnect == false);
210 
211  vNodes[max_outbound_full_relay - 1]->fDisconnect = false;
212 
213  // Add an onion peer, that will be protected because it is the only one for
214  // its network, so another peer gets disconnected instead.
215  SetMockTime(time_init);
216  AddRandomOutboundPeer(id, vNodes, *peerLogic, *connman, ConnectionType::OUTBOUND_FULL_RELAY, /*onion_peer=*/true);
217  SetMockTime(time_later);
218  peerLogic->CheckForStaleTipAndEvictPeers();
219 
220  for (int i = 0; i < max_outbound_full_relay - 2; ++i) {
221  BOOST_CHECK(vNodes[i]->fDisconnect == false);
222  }
223  BOOST_CHECK(vNodes[max_outbound_full_relay - 2]->fDisconnect == false);
224  BOOST_CHECK(vNodes[max_outbound_full_relay - 1]->fDisconnect == true);
225  BOOST_CHECK(vNodes[max_outbound_full_relay]->fDisconnect == false);
226 
227  // Add a second onion peer which won't be protected
228  SetMockTime(time_init);
229  AddRandomOutboundPeer(id, vNodes, *peerLogic, *connman, ConnectionType::OUTBOUND_FULL_RELAY, /*onion_peer=*/true);
230  SetMockTime(time_later);
231  peerLogic->CheckForStaleTipAndEvictPeers();
232 
233  BOOST_CHECK(vNodes.back()->fDisconnect == true);
234 
235  for (const CNode *node : vNodes) {
236  peerLogic->FinalizeNode(*node);
237  }
238 
239  connman->ClearTestNodes();
240 }
241 
242 BOOST_FIXTURE_TEST_CASE(block_relay_only_eviction, OutboundTest)
243 {
244  NodeId id{0};
245  auto connman = std::make_unique<ConnmanTestMsg>(0x1337, 0x1337, *m_node.addrman, *m_node.netgroupman, Params());
246  auto peerLogic = PeerManager::make(*connman, *m_node.addrman, nullptr, *m_node.chainman, *m_node.mempool, *m_node.warnings, {});
247 
248  constexpr int max_outbound_block_relay{MAX_BLOCK_RELAY_ONLY_CONNECTIONS};
249  constexpr int64_t MINIMUM_CONNECT_TIME{30};
250  CConnman::Options options;
252 
253  connman->Init(options);
254  std::vector<CNode*> vNodes;
255 
256  // Add block-relay-only peers up to the limit
257  for (int i = 0; i < max_outbound_block_relay; ++i) {
258  AddRandomOutboundPeer(id, vNodes, *peerLogic, *connman, ConnectionType::BLOCK_RELAY);
259  }
260  peerLogic->CheckForStaleTipAndEvictPeers();
261 
262  for (int i = 0; i < max_outbound_block_relay; ++i) {
263  BOOST_CHECK(vNodes[i]->fDisconnect == false);
264  }
265 
266  // Add an extra block-relay-only peer breaking the limit (mocks logic in ThreadOpenConnections)
267  AddRandomOutboundPeer(id, vNodes, *peerLogic, *connman, ConnectionType::BLOCK_RELAY);
268  peerLogic->CheckForStaleTipAndEvictPeers();
269 
270  // The extra peer should only get marked for eviction after MINIMUM_CONNECT_TIME
271  for (int i = 0; i < max_outbound_block_relay; ++i) {
272  BOOST_CHECK(vNodes[i]->fDisconnect == false);
273  }
274  BOOST_CHECK(vNodes.back()->fDisconnect == false);
275 
277  peerLogic->CheckForStaleTipAndEvictPeers();
278  for (int i = 0; i < max_outbound_block_relay; ++i) {
279  BOOST_CHECK(vNodes[i]->fDisconnect == false);
280  }
281  BOOST_CHECK(vNodes.back()->fDisconnect == true);
282 
283  // Update the last block time for the extra peer,
284  // and check that the next youngest peer gets evicted.
285  vNodes.back()->fDisconnect = false;
286  vNodes.back()->m_last_block_time = GetTime<std::chrono::seconds>();
287 
288  peerLogic->CheckForStaleTipAndEvictPeers();
289  for (int i = 0; i < max_outbound_block_relay - 1; ++i) {
290  BOOST_CHECK(vNodes[i]->fDisconnect == false);
291  }
292  BOOST_CHECK(vNodes[max_outbound_block_relay - 1]->fDisconnect == true);
293  BOOST_CHECK(vNodes.back()->fDisconnect == false);
294 
295  for (const CNode* node : vNodes) {
296  peerLogic->FinalizeNode(*node);
297  }
298  connman->ClearTestNodes();
299 }
300 
301 BOOST_AUTO_TEST_CASE(peer_discouragement)
302 {
304 
305  auto banman = std::make_unique<BanMan>(m_args.GetDataDirBase() / "banlist", nullptr, DEFAULT_MISBEHAVING_BANTIME);
306  auto connman = std::make_unique<ConnmanTestMsg>(0x1337, 0x1337, *m_node.addrman, *m_node.netgroupman, Params());
307  auto peerLogic = PeerManager::make(*connman, *m_node.addrman, banman.get(), *m_node.chainman, *m_node.mempool, *m_node.warnings, {});
308 
309  CNetAddr tor_netaddr;
310  BOOST_REQUIRE(
311  tor_netaddr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion"));
312  const CService tor_service{tor_netaddr, Params().GetDefaultPort()};
313 
314  const std::array<CAddress, 3> addr{CAddress{ip(0xa0b0c001), NODE_NONE},
315  CAddress{ip(0xa0b0c002), NODE_NONE},
316  CAddress{tor_service, NODE_NONE}};
317 
318  const CNetAddr other_addr{ip(0xa0b0ff01)}; // Not any of addr[].
319 
320  std::array<CNode*, 3> nodes;
321 
322  banman->ClearBanned();
323  NodeId id{0};
324  nodes[0] = new CNode{id++,
325  /*sock=*/nullptr,
326  addr[0],
327  /*nKeyedNetGroupIn=*/0,
328  /*nLocalHostNonceIn=*/0,
329  CAddress(),
330  /*addrNameIn=*/"",
332  /*inbound_onion=*/false,
333  /*network_key=*/1};
334  nodes[0]->SetCommonVersion(PROTOCOL_VERSION);
335  peerLogic->InitializeNode(*nodes[0], NODE_NETWORK);
336  nodes[0]->fSuccessfullyConnected = true;
337  connman->AddTestNode(*nodes[0]);
338  peerLogic->UnitTestMisbehaving(nodes[0]->GetId()); // Should be discouraged
339  BOOST_CHECK(peerLogic->SendMessages(*nodes[0]));
340 
341  BOOST_CHECK(banman->IsDiscouraged(addr[0]));
342  BOOST_CHECK(nodes[0]->fDisconnect);
343  BOOST_CHECK(!banman->IsDiscouraged(other_addr)); // Different address, not discouraged
344 
345  nodes[1] = new CNode{id++,
346  /*sock=*/nullptr,
347  addr[1],
348  /*nKeyedNetGroupIn=*/1,
349  /*nLocalHostNonceIn=*/1,
350  CAddress(),
351  /*addrNameIn=*/"",
353  /*inbound_onion=*/false,
354  /*network_key=*/1};
355  nodes[1]->SetCommonVersion(PROTOCOL_VERSION);
356  peerLogic->InitializeNode(*nodes[1], NODE_NETWORK);
357  nodes[1]->fSuccessfullyConnected = true;
358  connman->AddTestNode(*nodes[1]);
359  BOOST_CHECK(peerLogic->SendMessages(*nodes[1]));
360  // [0] is still discouraged/disconnected.
361  BOOST_CHECK(banman->IsDiscouraged(addr[0]));
362  BOOST_CHECK(nodes[0]->fDisconnect);
363  // [1] is not discouraged/disconnected yet.
364  BOOST_CHECK(!banman->IsDiscouraged(addr[1]));
365  BOOST_CHECK(!nodes[1]->fDisconnect);
366  peerLogic->UnitTestMisbehaving(nodes[1]->GetId());
367  BOOST_CHECK(peerLogic->SendMessages(*nodes[1]));
368  // Expect both [0] and [1] to be discouraged/disconnected now.
369  BOOST_CHECK(banman->IsDiscouraged(addr[0]));
370  BOOST_CHECK(nodes[0]->fDisconnect);
371  BOOST_CHECK(banman->IsDiscouraged(addr[1]));
372  BOOST_CHECK(nodes[1]->fDisconnect);
373 
374  // Make sure non-IP peers are discouraged and disconnected properly.
375 
376  nodes[2] = new CNode{id++,
377  /*sock=*/nullptr,
378  addr[2],
379  /*nKeyedNetGroupIn=*/1,
380  /*nLocalHostNonceIn=*/1,
381  CAddress(),
382  /*addrNameIn=*/"",
384  /*inbound_onion=*/false,
385  /*network_key=*/2};
386  nodes[2]->SetCommonVersion(PROTOCOL_VERSION);
387  peerLogic->InitializeNode(*nodes[2], NODE_NETWORK);
388  nodes[2]->fSuccessfullyConnected = true;
389  connman->AddTestNode(*nodes[2]);
390  peerLogic->UnitTestMisbehaving(nodes[2]->GetId());
391  BOOST_CHECK(peerLogic->SendMessages(*nodes[2]));
392  BOOST_CHECK(banman->IsDiscouraged(addr[0]));
393  BOOST_CHECK(banman->IsDiscouraged(addr[1]));
394  BOOST_CHECK(banman->IsDiscouraged(addr[2]));
395  BOOST_CHECK(nodes[0]->fDisconnect);
396  BOOST_CHECK(nodes[1]->fDisconnect);
397  BOOST_CHECK(nodes[2]->fDisconnect);
398 
399  for (CNode* node : nodes) {
400  peerLogic->FinalizeNode(*node);
401  }
402  connman->ClearTestNodes();
403 }
404 
406 {
408 
409  auto banman = std::make_unique<BanMan>(m_args.GetDataDirBase() / "banlist", nullptr, DEFAULT_MISBEHAVING_BANTIME);
410  auto connman = std::make_unique<CConnman>(0x1337, 0x1337, *m_node.addrman, *m_node.netgroupman, Params());
411  auto peerLogic = PeerManager::make(*connman, *m_node.addrman, banman.get(), *m_node.chainman, *m_node.mempool, *m_node.warnings, {});
412 
413  banman->ClearBanned();
414  int64_t nStartTime = GetTime();
415  SetMockTime(nStartTime); // Overrides future calls to GetTime()
416 
417  CAddress addr(ip(0xa0b0c001), NODE_NONE);
418  NodeId id{0};
419  CNode dummyNode{id++,
420  /*sock=*/nullptr,
421  addr,
422  /*nKeyedNetGroupIn=*/4,
423  /*nLocalHostNonceIn=*/4,
424  CAddress(),
425  /*addrNameIn=*/"",
427  /*inbound_onion=*/false,
428  /*network_key=*/1};
429  dummyNode.SetCommonVersion(PROTOCOL_VERSION);
430  peerLogic->InitializeNode(dummyNode, NODE_NETWORK);
431  dummyNode.fSuccessfullyConnected = true;
432 
433  peerLogic->UnitTestMisbehaving(dummyNode.GetId());
434  BOOST_CHECK(peerLogic->SendMessages(dummyNode));
435  BOOST_CHECK(banman->IsDiscouraged(addr));
436 
437  peerLogic->FinalizeNode(dummyNode);
438 }
439 
static Mutex g_msgproc_mutex
Mutex for anything that is only accessed via the msg processing thread.
Definition: net.h:1031
std::vector< B > randbytes(size_t len) noexcept
Generate random bytes.
Definition: random.h:297
static const int MAX_BLOCK_RELAY_ONLY_CONNECTIONS
Maximum number of block-relay-only outgoing connections.
Definition: net.h:73
void SetPeerConnectTimeout(std::chrono::seconds timeout)
Definition: net.h:45
BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
std::unique_ptr< node::Warnings > warnings
Manages all the node warnings.
Definition: context.h:91
ServiceFlags
nServices flags
Definition: protocol.h:309
Inbound connections are those initiated by a peer.
node::NodeContext m_node
Definition: bitcoin-gui.cpp:43
static constexpr size_t ADDR_TORV3_SIZE
Size of TORv3 address (in bytes).
Definition: netaddress.h:93
static std::unique_ptr< PeerManager > make(CConnman &connman, AddrMan &addrman, BanMan *banman, ChainstateManager &chainman, CTxMemPool &pool, node::Warnings &warnings, Options opts)
void AddRandomOutboundPeer(NodeId &id, std::vector< CNode *> &vNodes, PeerManager &peerLogic, ConnmanTestMsg &connman, ConnectionType connType, bool onion_peer=false)
int64_t GetTime()
DEPRECATED, see GetTime.
Definition: time.cpp:81
std::unique_ptr< const NetGroupManager > netgroupman
Definition: context.h:69
void FlushSendBuffer(CNode &node) const
Definition: net.cpp:99
std::unique_ptr< AddrMan > addrman
Definition: context.h:66
These are the default connections that we use to connect with the network.
uint16_t GetDefaultPort() const
Definition: chainparams.h:91
std::unique_ptr< CTxMemPool > mempool
Definition: context.h:68
static const std::string addr1
Definition: key_tests.cpp:31
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
#define LOCK(cs)
Definition: sync.h:258
FastRandomContext m_rng
Definition: setup_common.h:68
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:529
BOOST_AUTO_TEST_SUITE_END()
bool SetSpecial(std::string_view addr)
Parse a Tor or I2P address and set this object to it.
Definition: netaddress.cpp:212
virtual void FinalizeNode(const CNode &node)=0
Handle removal of a peer (clear state)
A CService with information about it as peer.
Definition: protocol.h:366
static const int PROTOCOL_VERSION
network protocol versioning
static CService ip(uint32_t i)
int64_t NodeId
Definition: net.h:103
static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS
The maximum number of peer connections to maintain.
Definition: net.h:81
virtual bool SendMessages(CNode &node) EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex)=0
Send queued protocol messages to a given node.
int m_max_automatic_connections
Definition: net.h:1078
bool IsRoutable() const
Definition: netaddress.cpp:462
Definition: messages.h:21
Network address.
Definition: netaddress.h:112
static constexpr unsigned int DEFAULT_MISBEHAVING_BANTIME
Definition: banman.h:19
std::string OnionToString(std::span< const uint8_t > addr)
Definition: netaddress.cpp:569
const CChainParams & Params()
Return the currently selected parameters.
uint64_t randbits(int bits) noexcept
Generate a random (bits)-bit integer.
Definition: random.h:204
ConnectionType
Different types of connections to a peer.
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
Definition: time.cpp:44
static const int MAX_OUTBOUND_FULL_RELAY_CONNECTIONS
Maximum number of automatic outgoing nodes over which we&#39;ll relay everything (blocks, tx, addrs, etc)
Definition: net.h:69
std::unique_ptr< CConnman > connman
Definition: context.h:67
Information about a peer.
Definition: net.h:679
static constexpr auto MINIMUM_CONNECT_TIME
Minimum time an outbound-peer-eviction candidate must be connected for, in order to evict...
virtual void InitializeNode(const CNode &node, ServiceFlags our_services)=0
Initialize a peer (setup state)
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
Definition: cs_main.cpp:8
BOOST_FIXTURE_TEST_CASE(stale_tip_peer_management, OutboundTest)
void AddTestNode(CNode &node)
Definition: net.h:61
std::unique_ptr< ChainstateManager > chainman
Definition: context.h:72
Testing setup that configures a complete environment.
Definition: setup_common.h:121
We use block-relay-only connections to help prevent against partition attacks.
#define BOOST_CHECK(expr)
Definition: object.cpp:16
std::unique_ptr< PeerManager > peerman
Definition: context.h:71