aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Atack <jon@atack.com>2021-04-10 16:11:03 +0200
committerJon Atack <jon@atack.com>2021-06-14 14:01:35 +0200
commitce02dd1ef1f7f54f33780b32f195d31c1cc87318 (patch)
tree45d2262216da1f6858f993ba06d68740483f1b40
parent70bbc62711643ec57cce620f9f7a0e1fe5fb6346 (diff)
downloadbitcoin-ce02dd1ef1f7f54f33780b32f195d31c1cc87318.tar.xz
p2p: extend inbound eviction protection by network to I2P peers
This commit extends our inbound eviction protection to I2P peers to favorise the diversity of peer connections, as peers connected through the I2P network are otherwise disadvantaged by our eviction criteria for their higher latency (higher min ping times) relative to IPv4 and IPv6 peers, as well as relative to Tor onion peers. The `networks` array is order-dependent in the case of a tie in candidate counts between networks (earlier array members receive priority in the case of a tie). Therefore, we place I2P candidates before localhost and onion ones in terms of opportunity to recover unused remaining protected slots from the previous iteration, guesstimating that most nodes allowing both onion and I2P inbounds will have more onion peers, followed by localhost, then I2P, as I2P support is only being added in the upcoming v22.0 release.
-rw-r--r--src/net.cpp7
-rw-r--r--src/net.h2
-rw-r--r--src/test/net_peer_eviction_tests.cpp10
3 files changed, 11 insertions, 8 deletions
diff --git a/src/net.cpp b/src/net.cpp
index a69d13436d..4d7c181330 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -908,16 +908,17 @@ void ProtectEvictionCandidatesByRatio(std::vector<NodeEvictionCandidate>& evicti
// Protect the half of the remaining nodes which have been connected the longest.
// This replicates the non-eviction implicit behavior, and precludes attacks that start later.
// To favorise the diversity of our peer connections, reserve up to half of these protected
- // spots for Tor/onion and localhost peers, even if they're not longest uptime overall.
+ // spots for Tor/onion, localhost and I2P peers, even if they're not longest uptime overall.
// This helps protect these higher-latency peers that tend to be otherwise
// disadvantaged under our eviction criteria.
const size_t initial_size = eviction_candidates.size();
const size_t total_protect_size{initial_size / 2};
- // Disadvantaged networks to protect: localhost and Tor/onion. In case of equal counts, earlier
+ // Disadvantaged networks to protect: I2P, localhost, Tor/onion. In case of equal counts, earlier
// array members have first opportunity to recover unused slots from the previous iteration.
struct Net { bool is_local; Network id; size_t count; };
- std::array<Net, 3> networks{{{/* localhost */ true, NET_MAX, 0}, {false, NET_ONION, 0}}};
+ std::array<Net, 3> networks{
+ {{false, NET_I2P, 0}, {/* localhost */ true, NET_MAX, 0}, {false, NET_ONION, 0}}};
// Count and store the number of eviction candidates per network.
for (Net& n : networks) {
diff --git a/src/net.h b/src/net.h
index e308ac5714..01658e8973 100644
--- a/src/net.h
+++ b/src/net.h
@@ -1236,6 +1236,8 @@ struct NodeEvictionCandidate
* - localhost peers, as manually configured hidden services not using
* `-bind=addr[:port]=onion` will not be detected as inbound onion connections
*
+ * - I2P peers
+ *
* This helps protect these privacy network peers, which tend to be otherwise
* disadvantaged under our eviction criteria for their higher min ping times
* relative to IPv4/IPv6 peers, and favorise the diversity of peer connections.
diff --git a/src/test/net_peer_eviction_tests.cpp b/src/test/net_peer_eviction_tests.cpp
index ec4aa50173..bf56e1bea7 100644
--- a/src/test/net_peer_eviction_tests.cpp
+++ b/src/test/net_peer_eviction_tests.cpp
@@ -109,10 +109,10 @@ BOOST_AUTO_TEST_CASE(peer_protection_test)
/* unprotected_peer_ids */ {0, 1, 2, 3, 4, 5},
random_context));
- // Test protection of onion and localhost peers...
+ // Test protection of onion, localhost, and I2P peers...
// Expect 1/4 onion peers to be protected from eviction,
- // if no localhost peers.
+ // if no localhost or I2P peers.
BOOST_CHECK(IsProtected(
num_peers, [](NodeEvictionCandidate& c) {
c.m_is_local = false;
@@ -123,7 +123,7 @@ BOOST_AUTO_TEST_CASE(peer_protection_test)
random_context));
// Expect 1/4 onion peers and 1/4 of the other peers to be protected,
- // sorted by longest uptime (lowest nTimeConnected), if no localhost peers.
+ // sorted by longest uptime (lowest nTimeConnected), if no localhost or I2P peers.
BOOST_CHECK(IsProtected(
num_peers, [](NodeEvictionCandidate& c) {
c.nTimeConnected = c.id;
@@ -135,7 +135,7 @@ BOOST_AUTO_TEST_CASE(peer_protection_test)
random_context));
// Expect 1/4 localhost peers to be protected from eviction,
- // if no onion peers.
+ // if no onion or I2P peers.
BOOST_CHECK(IsProtected(
num_peers, [](NodeEvictionCandidate& c) {
c.m_is_local = (c.id == 1 || c.id == 9 || c.id == 11);
@@ -146,7 +146,7 @@ BOOST_AUTO_TEST_CASE(peer_protection_test)
random_context));
// Expect 1/4 localhost peers and 1/4 of the other peers to be protected,
- // sorted by longest uptime (lowest nTimeConnected), if no onion peers.
+ // sorted by longest uptime (lowest nTimeConnected), if no onion or I2P peers.
BOOST_CHECK(IsProtected(
num_peers, [](NodeEvictionCandidate& c) {
c.nTimeConnected = c.id;