Bitcoin Core 32.99.0
P2P Digital Currency
peerman_tests.cpp
Go to the documentation of this file.
1// Copyright (c) 2024-present The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or https://www.opensource.org/licenses/mit-license.php.
4
5#include <chain.h>
6#include <chainparams.h>
7#include <consensus/params.h>
8#include <net_processing.h>
10#include <node/miner.h>
11#include <pow.h>
12#include <primitives/block.h>
13#include <protocol.h>
14#include <sync.h>
16#include <test/util/time.h>
17#include <util/check.h>
18#include <validation.h>
19#include <validationinterface.h>
20
21#include <boost/test/unit_test.hpp>
22
23#include <cstdint>
24#include <memory>
25
27
28
29static constexpr int64_t NODE_NETWORK_LIMITED_ALLOW_CONN_BLOCKS = 144;
30
31static void mineBlock(node::NodeContext& node, FakeNodeClock& clock, std::chrono::seconds block_time)
32{
33 auto curr_time = GetTime<std::chrono::seconds>();
34 clock.set(block_time); // update time so the block is created with it
35 auto& block_template_manager{*Assert(node.block_template_manager)};
36 auto block_template{block_template_manager.CreateNewTemplate({})};
37 BOOST_REQUIRE(block_template);
38 CBlock block{block_template->block};
39 while (!CheckProofOfWork(block.GetHash(), block.nBits, node.chainman->GetConsensus())) ++block.nNonce;
40 block.fChecked = true; // little speedup
41 clock.set(curr_time); // process block at current time
42 Assert(node.chainman->ProcessNewBlock(std::make_shared<const CBlock>(block), /*force_processing=*/true, /*min_pow_checked=*/true, nullptr));
43 node.validation_signals->SyncWithValidationInterfaceQueue(); // drain events queue
44}
45
46// Verifying when network-limited peer connections are desirable based on the node's proximity to the tip
47BOOST_AUTO_TEST_CASE(connections_desirable_service_flags)
48{
50 std::unique_ptr<PeerManager> peerman = PeerManager::make(*m_node.connman, *m_node.addrman, nullptr, *m_node.chainman, *m_node.mempool, *m_node.warnings, {});
51 auto consensus = m_node.chainman->GetParams().GetConsensus();
52
53 // Check we start connecting to full nodes
55 BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK | NODE_WITNESS));
56
57 // Make peerman aware of the initial best block and verify we accept limited peers when we start close to the tip time.
58 auto tip = WITH_LOCK(::cs_main, return m_node.chainman->ActiveChain().Tip());
59 uint64_t tip_block_time = tip->GetBlockTime();
60 int tip_block_height = tip->nHeight;
61 peerman->SetBestBlock(tip_block_height, std::chrono::seconds{tip_block_time});
62
63 clock.set(std::chrono::seconds{tip_block_time + 1}); // Set node time to tip time
64 BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS));
65
66 // Check we don't disallow limited peers connections when we are behind but still recoverable (below the connection safety window)
67 clock += std::chrono::seconds{consensus.nPowTargetSpacing * (NODE_NETWORK_LIMITED_ALLOW_CONN_BLOCKS - 1)};
68 BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS));
69
70 // Check we disallow limited peers connections when we are further than the limited peers safety window
71 clock += std::chrono::seconds{consensus.nPowTargetSpacing * 2};
72 BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK | NODE_WITNESS));
73
74 // By now, we tested that the connections desirable services flags change based on the node's time proximity to the tip.
75 // Now, perform the same tests for when the node receives a block.
76 m_node.validation_signals->RegisterValidationInterface(peerman.get());
77
78 // First, verify a block in the past doesn't enable limited peers connections
79 // At this point, our time is (NODE_NETWORK_LIMITED_ALLOW_CONN_BLOCKS + 1) * 10 minutes ahead the tip's time.
80 mineBlock(m_node, clock, /*block_time=*/std::chrono::seconds{tip_block_time + 1});
81 BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK | NODE_WITNESS));
82
83 // Verify a block close to the tip enables limited peers connections
84 mineBlock(m_node, clock, /*block_time=*/GetTime<std::chrono::seconds>());
85 BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS));
86
87 // Lastly, verify the stale tip checks can disallow limited peers connections after not receiving blocks for a prolonged period.
88 clock += std::chrono::seconds{consensus.nPowTargetSpacing * NODE_NETWORK_LIMITED_ALLOW_CONN_BLOCKS + 1};
89 BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK | NODE_WITNESS));
90}
91
node::NodeContext m_node
Definition: bitcoin-gui.cpp:48
#define Assert(val)
Identity function.
Definition: check.h:116
uint32_t nNonce
Definition: block.h:35
Definition: block.h:74
Helper to initialize the global NodeClock, let a duration elapse, and reset it after use in a test.
Definition: time.h:54
void set(NodeSeconds t)
Set mocktime.
Definition: time.h:71
static std::unique_ptr< PeerManager > make(CConnman &connman, AddrMan &addrman, BanMan *banman, ChainstateManager &chainman, CTxMemPool &pool, node::Warnings &warnings, Options opts)
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_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
Definition: messages.h:21
#define BOOST_CHECK(expr)
Definition: object.cpp:16
BOOST_AUTO_TEST_CASE(connections_desirable_service_flags)
static void mineBlock(node::NodeContext &node, FakeNodeClock &clock, std::chrono::seconds block_time)
static constexpr int64_t NODE_NETWORK_LIMITED_ALLOW_CONN_BLOCKS
Window, in blocks, for connecting to NODE_NETWORK_LIMITED peers.
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params &params)
Check whether a block hash satisfies the proof-of-work requirement specified by nBits.
Definition: pow.cpp:140
ServiceFlags
nServices flags
Definition: protocol.h:321
@ NODE_WITNESS
Definition: protocol.h:332
@ NODE_NETWORK_LIMITED
Definition: protocol.h:339
@ NODE_NETWORK
Definition: protocol.h:327
Identical to TestingSetup, but chain set to regtest.
Definition: setup_common.h:126
std::unique_ptr< ValidationSignals > validation_signals
Issues calls about blocks and transactions.
Definition: context.h:89
std::unique_ptr< CConnman > connman
Definition: context.h:68
std::unique_ptr< CTxMemPool > mempool
Definition: context.h:69
std::unique_ptr< AddrMan > addrman
Definition: context.h:67
std::unique_ptr< ChainstateManager > chainman
Definition: context.h:74
std::unique_ptr< node::Warnings > warnings
Manages all the node warnings.
Definition: context.h:92
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:299
FakeNodeClock clock