Bitcoin Core  26.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 <chainparams.h>
6 #include <node/miner.h>
7 #include <net_processing.h>
8 #include <pow.h>
10 #include <validation.h>
11 
12 #include <boost/test/unit_test.hpp>
13 
14 BOOST_FIXTURE_TEST_SUITE(peerman_tests, RegTestingSetup)
15 
16 
17 static constexpr int64_t NODE_NETWORK_LIMITED_ALLOW_CONN_BLOCKS = 144;
18 
19 static void mineBlock(const node::NodeContext& node, std::chrono::seconds block_time)
20 {
21  auto curr_time = GetTime<std::chrono::seconds>();
22  SetMockTime(block_time); // update time so the block is created with it
23  CBlock block = node::BlockAssembler{node.chainman->ActiveChainstate(), nullptr}.CreateNewBlock(CScript() << OP_TRUE)->block;
24  while (!CheckProofOfWork(block.GetHash(), block.nBits, node.chainman->GetConsensus())) ++block.nNonce;
25  block.fChecked = true; // little speedup
26  SetMockTime(curr_time); // process block at current time
27  Assert(node.chainman->ProcessNewBlock(std::make_shared<const CBlock>(block), /*force_processing=*/true, /*min_pow_checked=*/true, nullptr));
28  SyncWithValidationInterfaceQueue(); // drain events queue
29 }
30 
31 // Verifying when network-limited peer connections are desirable based on the node's proximity to the tip
32 BOOST_AUTO_TEST_CASE(connections_desirable_service_flags)
33 {
34  std::unique_ptr<PeerManager> peerman = PeerManager::make(*m_node.connman, *m_node.addrman, nullptr, *m_node.chainman, *m_node.mempool, {});
35  auto consensus = m_node.chainman->GetParams().GetConsensus();
36 
37  // Check we start connecting to full nodes
39  BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK | NODE_WITNESS));
40 
41  // Make peerman aware of the initial best block and verify we accept limited peers when we start close to the tip time.
42  auto tip = WITH_LOCK(::cs_main, return m_node.chainman->ActiveChain().Tip());
43  uint64_t tip_block_time = tip->GetBlockTime();
44  int tip_block_height = tip->nHeight;
45  peerman->SetBestBlock(tip_block_height, std::chrono::seconds{tip_block_time});
46 
47  SetMockTime(tip_block_time + 1); // Set node time to tip time
48  BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS));
49 
50  // Check we don't disallow limited peers connections when we are behind but still recoverable (below the connection safety window)
51  SetMockTime(GetTime<std::chrono::seconds>() + std::chrono::seconds{consensus.nPowTargetSpacing * (NODE_NETWORK_LIMITED_ALLOW_CONN_BLOCKS - 1)});
52  BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS));
53 
54  // Check we disallow limited peers connections when we are further than the limited peers safety window
55  SetMockTime(GetTime<std::chrono::seconds>() + std::chrono::seconds{consensus.nPowTargetSpacing * 2});
56  BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK | NODE_WITNESS));
57 
58  // By now, we tested that the connections desirable services flags change based on the node's time proximity to the tip.
59  // Now, perform the same tests for when the node receives a block.
60  RegisterValidationInterface(peerman.get());
61 
62  // First, verify a block in the past doesn't enable limited peers connections
63  // At this point, our time is (NODE_NETWORK_LIMITED_ALLOW_CONN_BLOCKS + 1) * 10 minutes ahead the tip's time.
64  mineBlock(m_node, /*block_time=*/std::chrono::seconds{tip_block_time + 1});
65  BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK | NODE_WITNESS));
66 
67  // Verify a block close to the tip enables limited peers connections
68  mineBlock(m_node, /*block_time=*/GetTime<std::chrono::seconds>());
69  BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS));
70 
71  // Lastly, verify the stale tip checks can disallow limited peers connections after not receiving blocks for a prolonged period.
72  SetMockTime(GetTime<std::chrono::seconds>() + std::chrono::seconds{consensus.nPowTargetSpacing * NODE_NETWORK_LIMITED_ALLOW_CONN_BLOCKS + 1});
73  BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK | NODE_WITNESS));
74 }
75 
node::NodeContext m_node
Definition: bitcoin-gui.cpp:37
#define Assert(val)
Identity function.
Definition: check.h:77
uint32_t nNonce
Definition: block.h:30
uint32_t nBits
Definition: block.h:29
uint256 GetHash() const
Definition: block.cpp:11
Definition: block.h:69
bool fChecked
Definition: block.h:75
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:414
static std::unique_ptr< PeerManager > make(CConnman &connman, AddrMan &addrman, BanMan *banman, ChainstateManager &chainman, CTxMemPool &pool, Options opts)
Generate a new block, without valid proof-of-work.
Definition: miner.h:135
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
Definition: cs_main.cpp:8
BOOST_AUTO_TEST_SUITE_END()
Definition: init.h:25
#define BOOST_CHECK(expr)
Definition: object.cpp:17
static void mineBlock(const node::NodeContext &node, std::chrono::seconds block_time)
BOOST_AUTO_TEST_CASE(connections_desirable_service_flags)
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:125
ServiceFlags
nServices flags
Definition: protocol.h:274
@ NODE_WITNESS
Definition: protocol.h:285
@ NODE_NETWORK_LIMITED
Definition: protocol.h:292
@ NODE_NETWORK
Definition: protocol.h:280
@ OP_TRUE
Definition: script.h:83
Identical to TestingSetup, but chain set to regtest.
Definition: setup_common.h:87
std::unique_ptr< CConnman > connman
Definition: context.h:56
std::unique_ptr< CTxMemPool > mempool
Definition: context.h:57
std::unique_ptr< AddrMan > addrman
Definition: context.h:55
std::unique_ptr< ChainstateManager > chainman
Definition: context.h:61
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:301
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
Definition: time.cpp:81
void RegisterValidationInterface(CValidationInterface *callbacks)
Register subscriber.
void SyncWithValidationInterfaceQueue()
This is a synonym for the following, which asserts certain locks are not held: std::promise<void> pro...