0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-02-08 10:31:50 -05:00

p2p: extend inbound eviction protection by network to CJDNS peers

This commit extends our inbound eviction protection to CJDNS peers to
favorise the diversity of peer connections, as peers connected
through the CJDNS network are otherwise disadvantaged by our eviction
criteria for their higher latency (higher min ping times) relative
to IPv4 and IPv6 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 CJDNS candidates before I2P, localhost, and onion
ones in terms of opportunity to recover unused remaining protected
slots from the previous iteration, estimating that most nodes allowing
several inbound privacy networks will have more onion, localhost or
I2P peers than CJDNS ones, as CJDNS support is only being added in the
upcoming v23.0 release.
This commit is contained in:
Jon Atack 2022-01-26 09:01:42 +01:00
parent dd405add6e
commit f7b8094d61
No known key found for this signature in database
GPG key ID: 796C4109063D4EAF
3 changed files with 15 additions and 13 deletions

View file

@ -918,17 +918,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, localhost and I2P peers, even if they're not longest uptime overall.
// This helps protect these higher-latency peers that tend to be otherwise
// spots for Tor/onion, localhost, I2P, and CJDNS 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: I2P, localhost, Tor/onion. In case of equal counts, earlier
// array members have first opportunity to recover unused slots from the previous iteration.
// Disadvantaged networks to protect. In the case of equal counts, earlier array members
// have the 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{
{{false, NET_I2P, 0}, {/* localhost */ true, NET_MAX, 0}, {false, NET_ONION, 0}}};
std::array<Net, 4> networks{
{{false, NET_CJDNS, 0}, {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) {

View file

@ -1307,6 +1307,8 @@ struct NodeEvictionCandidate
*
* - I2P peers
*
* - CJDNS 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.

View file

@ -90,7 +90,7 @@ BOOST_AUTO_TEST_CASE(peer_protection_test)
// Test protection of onion, localhost, and I2P peers...
// Expect 1/4 onion peers to be protected from eviction,
// if no localhost or I2P peers.
// if no localhost, I2P, or CJDNS peers.
BOOST_CHECK(IsProtected(
num_peers, [](NodeEvictionCandidate& c) {
c.m_is_local = false;
@ -101,7 +101,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 m_connected), if no localhost or I2P peers.
// sorted by longest uptime (lowest m_connected), if no localhost, I2P or CJDNS peers.
BOOST_CHECK(IsProtected(
num_peers, [](NodeEvictionCandidate& c) {
c.m_connected = std::chrono::seconds{c.id};
@ -113,7 +113,7 @@ BOOST_AUTO_TEST_CASE(peer_protection_test)
random_context));
// Expect 1/4 localhost peers to be protected from eviction,
// if no onion or I2P peers.
// if no onion, I2P, or CJDNS peers.
BOOST_CHECK(IsProtected(
num_peers, [](NodeEvictionCandidate& c) {
c.m_is_local = (c.id == 1 || c.id == 9 || c.id == 11);
@ -124,7 +124,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 m_connected), if no onion or I2P peers.
// sorted by longest uptime (lowest m_connected), if no onion, I2P, or CJDNS peers.
BOOST_CHECK(IsProtected(
num_peers, [](NodeEvictionCandidate& c) {
c.m_connected = std::chrono::seconds{c.id};
@ -136,7 +136,7 @@ BOOST_AUTO_TEST_CASE(peer_protection_test)
random_context));
// Expect 1/4 I2P peers to be protected from eviction,
// if no onion or localhost peers.
// if no onion, localhost, or CJDNS peers.
BOOST_CHECK(IsProtected(
num_peers, [](NodeEvictionCandidate& c) {
c.m_is_local = false;
@ -146,8 +146,8 @@ BOOST_AUTO_TEST_CASE(peer_protection_test)
/*unprotected_peer_ids=*/{},
random_context));
// Expect 1/4 I2P peers and 1/4 of the other peers to be protected,
// sorted by longest uptime (lowest m_connected), if no onion or localhost peers.
// Expect 1/4 I2P peers and 1/4 of the other peers to be protected, sorted
// by longest uptime (lowest m_connected), if no onion, localhost, or CJDNS peers.
BOOST_CHECK(IsProtected(
num_peers, [](NodeEvictionCandidate& c) {
c.m_connected = std::chrono::seconds{c.id};