Skip to content

Commit 7a91b51

Browse files
71d1452 refactor: enumerate each CNode argument on a separate line (Kittywhiskers Van Gogh) f8d1e5b merge bitcoin#25174: Add thread safety related annotations for CNode and Peer (Kittywhiskers Van Gogh) 4847f6e refactor: move `m_initial_sync_finished` out of header (Kittywhiskers Van Gogh) dba4cf0 merge bitcoin#25591: Version handshake to libtest_util (Kittywhiskers Van Gogh) b9b13bd merge bitcoin#24141: Rename message_command variables in src/net* and src/rpc/net.cpp (Kittywhiskers Van Gogh) a6aa373 merge bitcoin#20196: fix GetListenPort() to derive the proper port (Kittywhiskers Van Gogh) c443cf4 merge bitcoin#24078: Rename CNetMessage::m_command with CNetMessage::m_type (Kittywhiskers Van Gogh) 182e31d merge bitcoin#23801: Change time variable type from int64_t to std::chrono::seconds in net_processing.cpp (Kittywhiskers Van Gogh) 6e6c944 merge bitcoin#23758: Use type-safe mockable time for peer connection time (Kittywhiskers Van Gogh) 7beeae7 merge bitcoin#23614: add unit test for block-relay-only eviction (Kittywhiskers Van Gogh) cf8f17e merge bitcoin#22735: Don't return an optional from TransportDeserializer::GetMessage() (Kittywhiskers Van Gogh) 224fb68 merge bitcoin#20541: Move special CAddress-without-nTime logic to net_processing (Kittywhiskers Van Gogh) 30ac41e merge bitcoin#22284: performance improvements to ProtectEvictionCandidatesByRatio() (Kittywhiskers Van Gogh) ad4369f merge bitcoin#21571: make sure non-IP peers get discouraged and disconnected (Kittywhiskers Van Gogh) Pull request description: ## Breaking Changes None expected. ## Checklist: - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas **(note: N/A)** - [x] I have added or updated relevant unit/integration/functional/e2e tests - [x] I have made corresponding changes to the documentation **(note: N/A)** - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ ACKs for top commit: PastaPastaPasta: utACK 71d1452 UdjinM6: utACK 71d1452 Tree-SHA512: b214d50fd87a046f22a9b3baf676483b4eee45ad267a4e501b221bbc77ef1e4532f0ad1fc8931be66761a9c50f2033ceeabbaae2bdb42f7c9edf7708bac8a9eb
2 parents 87fc2da + 71d1452 commit 7a91b51

25 files changed

+1092
-381
lines changed

src/Makefile.bench.include

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ bench_bench_dash_SOURCES = \
4040
bench/mempool_stress.cpp \
4141
bench/nanobench.h \
4242
bench/nanobench.cpp \
43+
bench/peer_eviction.cpp \
4344
bench/rpc_blockchain.cpp \
4445
bench/rpc_mempool.cpp \
4546
bench/util_time.cpp \

src/bench/peer_eviction.cpp

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
// Copyright (c) 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 <bench/bench.h>
6+
#include <net.h>
7+
#include <netaddress.h>
8+
#include <random.h>
9+
#include <test/util/net.h>
10+
#include <test/util/setup_common.h>
11+
12+
#include <algorithm>
13+
#include <functional>
14+
#include <vector>
15+
16+
static void EvictionProtectionCommon(
17+
benchmark::Bench& bench,
18+
int num_candidates,
19+
std::function<void(NodeEvictionCandidate&)> candidate_setup_fn)
20+
{
21+
using Candidates = std::vector<NodeEvictionCandidate>;
22+
FastRandomContext random_context{true};
23+
bench.warmup(100).epochIterations(1100);
24+
25+
Candidates candidates{GetRandomNodeEvictionCandidates(num_candidates, random_context)};
26+
for (auto& c : candidates) {
27+
candidate_setup_fn(c);
28+
}
29+
30+
std::vector<Candidates> copies{bench.epochs() * bench.epochIterations(), candidates};
31+
size_t i{0};
32+
bench.run([&] {
33+
ProtectEvictionCandidatesByRatio(copies.at(i));
34+
++i;
35+
});
36+
}
37+
38+
/* Benchmarks */
39+
40+
static void EvictionProtection0Networks250Candidates(benchmark::Bench& bench)
41+
{
42+
EvictionProtectionCommon(
43+
bench,
44+
250 /* num_candidates */,
45+
[](NodeEvictionCandidate& c) {
46+
c.m_connected = std::chrono::seconds{c.id};
47+
c.m_network = NET_IPV4;
48+
});
49+
}
50+
51+
static void EvictionProtection1Networks250Candidates(benchmark::Bench& bench)
52+
{
53+
EvictionProtectionCommon(
54+
bench,
55+
250 /* num_candidates */,
56+
[](NodeEvictionCandidate& c) {
57+
c.m_connected = std::chrono::seconds{c.id};
58+
c.m_is_local = false;
59+
if (c.id >= 130 && c.id < 240) { // 110 Tor
60+
c.m_network = NET_ONION;
61+
} else {
62+
c.m_network = NET_IPV4;
63+
}
64+
});
65+
}
66+
67+
static void EvictionProtection2Networks250Candidates(benchmark::Bench& bench)
68+
{
69+
EvictionProtectionCommon(
70+
bench,
71+
250 /* num_candidates */,
72+
[](NodeEvictionCandidate& c) {
73+
c.m_connected = std::chrono::seconds{c.id};
74+
c.m_is_local = false;
75+
if (c.id >= 90 && c.id < 160) { // 70 Tor
76+
c.m_network = NET_ONION;
77+
} else if (c.id >= 170 && c.id < 250) { // 80 I2P
78+
c.m_network = NET_I2P;
79+
} else {
80+
c.m_network = NET_IPV4;
81+
}
82+
});
83+
}
84+
85+
static void EvictionProtection3Networks050Candidates(benchmark::Bench& bench)
86+
{
87+
EvictionProtectionCommon(
88+
bench,
89+
50 /* num_candidates */,
90+
[](NodeEvictionCandidate& c) {
91+
c.m_connected = std::chrono::seconds{c.id};
92+
c.m_is_local = (c.id == 28 || c.id == 47); // 2 localhost
93+
if (c.id >= 30 && c.id < 47) { // 17 I2P
94+
c.m_network = NET_I2P;
95+
} else if (c.id >= 24 && c.id < 28) { // 4 Tor
96+
c.m_network = NET_ONION;
97+
} else {
98+
c.m_network = NET_IPV4;
99+
}
100+
});
101+
}
102+
103+
static void EvictionProtection3Networks100Candidates(benchmark::Bench& bench)
104+
{
105+
EvictionProtectionCommon(
106+
bench,
107+
100 /* num_candidates */,
108+
[](NodeEvictionCandidate& c) {
109+
c.m_connected = std::chrono::seconds{c.id};
110+
c.m_is_local = (c.id >= 55 && c.id < 60); // 5 localhost
111+
if (c.id >= 70 && c.id < 80) { // 10 I2P
112+
c.m_network = NET_I2P;
113+
} else if (c.id >= 80 && c.id < 96) { // 16 Tor
114+
c.m_network = NET_ONION;
115+
} else {
116+
c.m_network = NET_IPV4;
117+
}
118+
});
119+
}
120+
121+
static void EvictionProtection3Networks250Candidates(benchmark::Bench& bench)
122+
{
123+
EvictionProtectionCommon(
124+
bench,
125+
250 /* num_candidates */,
126+
[](NodeEvictionCandidate& c) {
127+
c.m_connected = std::chrono::seconds{c.id};
128+
c.m_is_local = (c.id >= 140 && c.id < 160); // 20 localhost
129+
if (c.id >= 170 && c.id < 180) { // 10 I2P
130+
c.m_network = NET_I2P;
131+
} else if (c.id >= 190 && c.id < 240) { // 50 Tor
132+
c.m_network = NET_ONION;
133+
} else {
134+
c.m_network = NET_IPV4;
135+
}
136+
});
137+
}
138+
139+
// Candidate numbers used for the benchmarks:
140+
// - 50 candidates simulates a possible use of -maxconnections
141+
// - 100 candidates approximates an average node with default settings
142+
// - 250 candidates is the number of peers reported by operators of busy nodes
143+
144+
// No disadvantaged networks, with 250 eviction candidates.
145+
BENCHMARK(EvictionProtection0Networks250Candidates);
146+
147+
// 1 disadvantaged network (Tor) with 250 eviction candidates.
148+
BENCHMARK(EvictionProtection1Networks250Candidates);
149+
150+
// 2 disadvantaged networks (I2P, Tor) with 250 eviction candidates.
151+
BENCHMARK(EvictionProtection2Networks250Candidates);
152+
153+
// 3 disadvantaged networks (I2P/localhost/Tor) with 50/100/250 eviction candidates.
154+
BENCHMARK(EvictionProtection3Networks050Candidates);
155+
BENCHMARK(EvictionProtection3Networks100Candidates);
156+
BENCHMARK(EvictionProtection3Networks250Candidates);

src/init.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2477,8 +2477,6 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
24772477
LogPrintf("::ChainActive().Height() = %d\n", chain_active_height);
24782478
if (node.peerman) node.peerman->SetBestHeight(chain_active_height);
24792479

2480-
Discover();
2481-
24822480
// Map ports with UPnP or NAT-PMP.
24832481
StartMapPort(args.GetBoolArg("-upnp", DEFAULT_UPNP), args.GetBoolArg("-natpmp", DEFAULT_NATPMP));
24842482

@@ -2495,15 +2493,18 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
24952493
connOptions.nSendBufferMaxSize = 1000 * args.GetArg("-maxsendbuffer", DEFAULT_MAXSENDBUFFER);
24962494
connOptions.nReceiveFloodSize = 1000 * args.GetArg("-maxreceivebuffer", DEFAULT_MAXRECEIVEBUFFER);
24972495
connOptions.m_added_nodes = args.GetArgs("-addnode");
2498-
24992496
connOptions.nMaxOutboundLimit = 1024 * 1024 * args.GetArg("-maxuploadtarget", DEFAULT_MAX_UPLOAD_TARGET);
25002497
connOptions.m_peer_connect_timeout = peer_connect_timeout;
25012498

2499+
// Port to bind to if `-bind=addr` is provided without a `:port` suffix.
2500+
const uint16_t default_bind_port =
2501+
static_cast<uint16_t>(args.GetArg("-port", Params().GetDefaultPort()));
2502+
25022503
for (const std::string& bind_arg : args.GetArgs("-bind")) {
25032504
CService bind_addr;
25042505
const size_t index = bind_arg.rfind('=');
25052506
if (index == std::string::npos) {
2506-
if (Lookup(bind_arg, bind_addr, GetListenPort(), false)) {
2507+
if (Lookup(bind_arg, bind_addr, default_bind_port, /*fAllowLookup=*/false)) {
25072508
connOptions.vBinds.push_back(bind_addr);
25082509
continue;
25092510
}
@@ -2548,6 +2549,12 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
25482549
StartTorControl(onion_service_target);
25492550
}
25502551

2552+
if (connOptions.bind_on_any) {
2553+
// Only add all IP addresses of the machine if we would be listening on
2554+
// any address - 0.0.0.0 (IPv4) and :: (IPv6).
2555+
Discover();
2556+
}
2557+
25512558
for (const auto& net : args.GetArgs("-whitelist")) {
25522559
NetWhitelistPermissions subnet;
25532560
bilingual_str error;

src/masternode/utils.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ void CMasternodeUtils::DoMaintenance(CConnman& connman, CDeterministicMNManager&
4949
connman.ForEachNode(CConnman::AllNodes, [&](CNode* pnode) {
5050
if (pnode->m_masternode_probe_connection) {
5151
// we're not disconnecting masternode probes for at least PROBE_WAIT_INTERVAL seconds
52-
if (GetTimeSeconds() - pnode->nTimeConnected < PROBE_WAIT_INTERVAL) return;
52+
if (GetTime<std::chrono::seconds>() - pnode->m_connected < PROBE_WAIT_INTERVAL) return;
5353
} else {
5454
// we're only disconnecting m_masternode_connection connections
5555
if (!pnode->m_masternode_connection) return;
@@ -67,7 +67,7 @@ void CMasternodeUtils::DoMaintenance(CConnman& connman, CDeterministicMNManager&
6767
if (pnode->IsInboundConn()) {
6868
return;
6969
}
70-
} else if (GetTimeSeconds() - pnode->nTimeConnected < 5) {
70+
} else if (GetTime<std::chrono::seconds>() - pnode->m_connected < 5s) {
7171
// non-verified, give it some time to verify itself
7272
return;
7373
} else if (pnode->qwatch) {

0 commit comments

Comments
 (0)