mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 03:52:49 +01:00
merge bitcoin#24165: extend inbound eviction protection by network to CJDNS peers
This commit is contained in:
parent
d52724d039
commit
5436b6a82d
12
src/net.cpp
12
src/net.cpp
@ -1026,17 +1026,17 @@ void ProtectEvictionCandidatesByRatio(std::vector<NodeEvictionCandidate>& evicti
|
|||||||
// Protect the half of the remaining nodes which have been connected the longest.
|
// 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.
|
// 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
|
// 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.
|
// spots for Tor/onion, localhost, I2P, and CJDNS peers, even if they're not longest uptime
|
||||||
// This helps protect these higher-latency peers that tend to be otherwise
|
// overall. This helps protect these higher-latency peers that tend to be otherwise
|
||||||
// disadvantaged under our eviction criteria.
|
// disadvantaged under our eviction criteria.
|
||||||
const size_t initial_size = eviction_candidates.size();
|
const size_t initial_size = eviction_candidates.size();
|
||||||
const size_t total_protect_size{initial_size / 2};
|
const size_t total_protect_size{initial_size / 2};
|
||||||
|
|
||||||
// Disadvantaged networks to protect: I2P, localhost, Tor/onion. In case of equal counts, earlier
|
// Disadvantaged networks to protect. In the case of equal counts, earlier array members
|
||||||
// array members have first opportunity to recover unused slots from the previous iteration.
|
// have the first opportunity to recover unused slots from the previous iteration.
|
||||||
struct Net { bool is_local; Network id; size_t count; };
|
struct Net { bool is_local; Network id; size_t count; };
|
||||||
std::array<Net, 3> networks{
|
std::array<Net, 4> networks{
|
||||||
{{false, NET_I2P, 0}, {/* localhost */ true, NET_MAX, 0}, {false, NET_ONION, 0}}};
|
{{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.
|
// Count and store the number of eviction candidates per network.
|
||||||
for (Net& n : networks) {
|
for (Net& n : networks) {
|
||||||
|
@ -1661,6 +1661,8 @@ size_t GetRequestedObjectCount(NodeId nodeId) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
|||||||
*
|
*
|
||||||
* - I2P peers
|
* - I2P peers
|
||||||
*
|
*
|
||||||
|
* - CJDNS peers
|
||||||
|
*
|
||||||
* This helps protect these privacy network peers, which tend to be otherwise
|
* This helps protect these privacy network peers, which tend to be otherwise
|
||||||
* disadvantaged under our eviction criteria for their higher min ping times
|
* disadvantaged under our eviction criteria for their higher min ping times
|
||||||
* relative to IPv4/IPv6 peers, and favorise the diversity of peer connections.
|
* relative to IPv4/IPv6 peers, and favorise the diversity of peer connections.
|
||||||
|
@ -112,7 +112,7 @@ BOOST_AUTO_TEST_CASE(peer_protection_test)
|
|||||||
// Test protection of onion, localhost, and I2P peers...
|
// Test protection of onion, localhost, and I2P peers...
|
||||||
|
|
||||||
// Expect 1/4 onion peers to be protected from eviction,
|
// 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(
|
BOOST_CHECK(IsProtected(
|
||||||
num_peers, [](NodeEvictionCandidate& c) {
|
num_peers, [](NodeEvictionCandidate& c) {
|
||||||
c.m_is_local = false;
|
c.m_is_local = false;
|
||||||
@ -123,7 +123,7 @@ BOOST_AUTO_TEST_CASE(peer_protection_test)
|
|||||||
random_context));
|
random_context));
|
||||||
|
|
||||||
// Expect 1/4 onion peers and 1/4 of the other peers to be protected,
|
// Expect 1/4 onion peers and 1/4 of the other peers to be protected,
|
||||||
// sorted by longest uptime (lowest nTimeConnected), if no localhost or I2P peers.
|
// sorted by longest uptime (lowest nTimeConnected), if no localhost, I2P or CJDNS peers.
|
||||||
BOOST_CHECK(IsProtected(
|
BOOST_CHECK(IsProtected(
|
||||||
num_peers, [](NodeEvictionCandidate& c) {
|
num_peers, [](NodeEvictionCandidate& c) {
|
||||||
c.nTimeConnected = c.id;
|
c.nTimeConnected = c.id;
|
||||||
@ -135,7 +135,7 @@ BOOST_AUTO_TEST_CASE(peer_protection_test)
|
|||||||
random_context));
|
random_context));
|
||||||
|
|
||||||
// Expect 1/4 localhost peers to be protected from eviction,
|
// 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(
|
BOOST_CHECK(IsProtected(
|
||||||
num_peers, [](NodeEvictionCandidate& c) {
|
num_peers, [](NodeEvictionCandidate& c) {
|
||||||
c.m_is_local = (c.id == 1 || c.id == 9 || c.id == 11);
|
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));
|
random_context));
|
||||||
|
|
||||||
// Expect 1/4 localhost peers and 1/4 of the other peers to be protected,
|
// Expect 1/4 localhost peers and 1/4 of the other peers to be protected,
|
||||||
// sorted by longest uptime (lowest nTimeConnected), if no onion or I2P peers.
|
// sorted by longest uptime (lowest nTimeConnected), if no onion, I2P, or CJDNS peers.
|
||||||
BOOST_CHECK(IsProtected(
|
BOOST_CHECK(IsProtected(
|
||||||
num_peers, [](NodeEvictionCandidate& c) {
|
num_peers, [](NodeEvictionCandidate& c) {
|
||||||
c.nTimeConnected = c.id;
|
c.nTimeConnected = c.id;
|
||||||
@ -158,7 +158,7 @@ BOOST_AUTO_TEST_CASE(peer_protection_test)
|
|||||||
random_context));
|
random_context));
|
||||||
|
|
||||||
// Expect 1/4 I2P peers to be protected from eviction,
|
// 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(
|
BOOST_CHECK(IsProtected(
|
||||||
num_peers, [](NodeEvictionCandidate& c) {
|
num_peers, [](NodeEvictionCandidate& c) {
|
||||||
c.m_is_local = false;
|
c.m_is_local = false;
|
||||||
@ -168,8 +168,8 @@ BOOST_AUTO_TEST_CASE(peer_protection_test)
|
|||||||
/* unprotected_peer_ids */ {},
|
/* unprotected_peer_ids */ {},
|
||||||
random_context));
|
random_context));
|
||||||
|
|
||||||
// Expect 1/4 I2P peers and 1/4 of the other peers to be protected,
|
// Expect 1/4 I2P peers and 1/4 of the other peers to be protected, sorted
|
||||||
// sorted by longest uptime (lowest nTimeConnected), if no onion or localhost peers.
|
// by longest uptime (lowest nTimeConnected), if no onion, localhost, or CJDNS peers.
|
||||||
BOOST_CHECK(IsProtected(
|
BOOST_CHECK(IsProtected(
|
||||||
num_peers, [](NodeEvictionCandidate& c) {
|
num_peers, [](NodeEvictionCandidate& c) {
|
||||||
c.nTimeConnected = c.id;
|
c.nTimeConnected = c.id;
|
||||||
@ -180,6 +180,29 @@ BOOST_AUTO_TEST_CASE(peer_protection_test)
|
|||||||
/* unprotected_peer_ids */ {3, 5, 6, 7, 8, 11},
|
/* unprotected_peer_ids */ {3, 5, 6, 7, 8, 11},
|
||||||
random_context));
|
random_context));
|
||||||
|
|
||||||
|
// Expect 1/4 CJDNS peers to be protected from eviction,
|
||||||
|
// if no onion, localhost, or I2P peers.
|
||||||
|
BOOST_CHECK(IsProtected(
|
||||||
|
num_peers, [](NodeEvictionCandidate& c) {
|
||||||
|
c.m_is_local = false;
|
||||||
|
c.m_network = (c.id == 2 || c.id == 7 || c.id == 10) ? NET_CJDNS : NET_IPV4;
|
||||||
|
},
|
||||||
|
/*protected_peer_ids=*/{2, 7, 10},
|
||||||
|
/*unprotected_peer_ids=*/{},
|
||||||
|
random_context));
|
||||||
|
|
||||||
|
// Expect 1/4 CJDNS peers and 1/4 of the other peers to be protected, sorted
|
||||||
|
// by longest uptime (lowest nTimeConnected), if no onion, localhost, or I2P peers.
|
||||||
|
BOOST_CHECK(IsProtected(
|
||||||
|
num_peers, [](NodeEvictionCandidate& c) {
|
||||||
|
c.nTimeConnected = c.id;
|
||||||
|
c.m_is_local = false;
|
||||||
|
c.m_network = (c.id == 4 || c.id > 8) ? NET_CJDNS : NET_IPV6;
|
||||||
|
},
|
||||||
|
/*protected_peer_ids=*/{0, 1, 2, 4, 9, 10},
|
||||||
|
/*unprotected_peer_ids=*/{3, 5, 6, 7, 8, 11},
|
||||||
|
random_context));
|
||||||
|
|
||||||
// Tests with 2 networks...
|
// Tests with 2 networks...
|
||||||
|
|
||||||
// Combined test: expect having 1 localhost and 1 onion peer out of 4 to
|
// Combined test: expect having 1 localhost and 1 onion peer out of 4 to
|
||||||
@ -311,16 +334,16 @@ BOOST_AUTO_TEST_CASE(peer_protection_test)
|
|||||||
BOOST_CHECK(IsProtected(
|
BOOST_CHECK(IsProtected(
|
||||||
4, [](NodeEvictionCandidate& c) {
|
4, [](NodeEvictionCandidate& c) {
|
||||||
c.nTimeConnected = c.id;
|
c.nTimeConnected = c.id;
|
||||||
c.m_is_local = (c.id == 3);
|
c.m_is_local = (c.id == 2);
|
||||||
if (c.id == 4) {
|
if (c.id == 3) {
|
||||||
c.m_network = NET_I2P;
|
c.m_network = NET_I2P;
|
||||||
} else if (c.id == 2) {
|
} else if (c.id == 1) {
|
||||||
c.m_network = NET_ONION;
|
c.m_network = NET_ONION;
|
||||||
} else {
|
} else {
|
||||||
c.m_network = NET_IPV6;
|
c.m_network = NET_IPV6;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/* protected_peer_ids */ {0, 4},
|
/* protected_peer_ids */ {0, 3},
|
||||||
/* unprotected_peer_ids */ {1, 2},
|
/* unprotected_peer_ids */ {1, 2},
|
||||||
random_context));
|
random_context));
|
||||||
|
|
||||||
@ -438,15 +461,15 @@ BOOST_AUTO_TEST_CASE(peer_protection_test)
|
|||||||
/* unprotected_peer_ids */ {6, 7, 8, 9, 10, 11, 16, 19, 20, 21, 22, 23},
|
/* unprotected_peer_ids */ {6, 7, 8, 9, 10, 11, 16, 19, 20, 21, 22, 23},
|
||||||
random_context));
|
random_context));
|
||||||
|
|
||||||
// Combined test: expect having 8 localhost, 4 I2P, and 3 onion peers out of
|
// Combined test: expect having 8 localhost, 4 CJDNS, and 3 onion peers out
|
||||||
// 24 to protect 2 of each (6 total), plus 6 others for 12/24 total, sorted
|
// of 24 to protect 2 of each (6 total), plus 6 others for 12/24 total,
|
||||||
// by longest uptime.
|
// sorted by longest uptime.
|
||||||
BOOST_CHECK(IsProtected(
|
BOOST_CHECK(IsProtected(
|
||||||
24, [](NodeEvictionCandidate& c) {
|
24, [](NodeEvictionCandidate& c) {
|
||||||
c.nTimeConnected = c.id;
|
c.nTimeConnected = c.id;
|
||||||
c.m_is_local = (c.id > 15);
|
c.m_is_local = (c.id > 15);
|
||||||
if (c.id > 10 && c.id < 15) {
|
if (c.id > 10 && c.id < 15) {
|
||||||
c.m_network = NET_I2P;
|
c.m_network = NET_CJDNS;
|
||||||
} else if (c.id > 6 && c.id < 10) {
|
} else if (c.id > 6 && c.id < 10) {
|
||||||
c.m_network = NET_ONION;
|
c.m_network = NET_ONION;
|
||||||
} else {
|
} else {
|
||||||
@ -456,6 +479,116 @@ BOOST_AUTO_TEST_CASE(peer_protection_test)
|
|||||||
/* protected_peer_ids */ {0, 1, 2, 3, 4, 5, 7, 8, 11, 12, 16, 17},
|
/* protected_peer_ids */ {0, 1, 2, 3, 4, 5, 7, 8, 11, 12, 16, 17},
|
||||||
/* unprotected_peer_ids */ {6, 9, 10, 13, 14, 15, 18, 19, 20, 21, 22, 23},
|
/* unprotected_peer_ids */ {6, 9, 10, 13, 14, 15, 18, 19, 20, 21, 22, 23},
|
||||||
random_context));
|
random_context));
|
||||||
|
|
||||||
|
// Tests with 4 networks...
|
||||||
|
|
||||||
|
// Combined test: expect having 1 CJDNS, 1 I2P, 1 localhost and 1 onion peer
|
||||||
|
// out of 5 to protect 1 CJDNS, 0 I2P, 0 localhost, 0 onion and 1 other peer
|
||||||
|
// (2 total), sorted by longest uptime; stable sort breaks tie with array
|
||||||
|
// order of CJDNS first.
|
||||||
|
BOOST_CHECK(IsProtected(
|
||||||
|
5, [](NodeEvictionCandidate& c) {
|
||||||
|
c.nTimeConnected = c.id;
|
||||||
|
c.m_is_local = (c.id == 3);
|
||||||
|
if (c.id == 4) {
|
||||||
|
c.m_network = NET_CJDNS;
|
||||||
|
} else if (c.id == 1) {
|
||||||
|
c.m_network = NET_I2P;
|
||||||
|
} else if (c.id == 2) {
|
||||||
|
c.m_network = NET_ONION;
|
||||||
|
} else {
|
||||||
|
c.m_network = NET_IPV6;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/* protected_peer_ids */ {0, 4},
|
||||||
|
/* unprotected_peer_ids */ {1, 2, 3},
|
||||||
|
random_context));
|
||||||
|
|
||||||
|
// Combined test: expect having 1 CJDNS, 1 I2P, 1 localhost and 1 onion peer
|
||||||
|
// out of 7 to protect 1 CJDNS, 0, I2P, 0 localhost, 0 onion and 2 other
|
||||||
|
// peers (3 total) sorted by longest uptime; stable sort breaks tie with
|
||||||
|
// array order of CJDNS first.
|
||||||
|
BOOST_CHECK(IsProtected(
|
||||||
|
7, [](NodeEvictionCandidate& c) {
|
||||||
|
c.nTimeConnected = c.id;
|
||||||
|
c.m_is_local = (c.id == 4);
|
||||||
|
if (c.id == 6) {
|
||||||
|
c.m_network = NET_CJDNS;
|
||||||
|
} else if (c.id == 5) {
|
||||||
|
c.m_network = NET_I2P;
|
||||||
|
} else if (c.id == 3) {
|
||||||
|
c.m_network = NET_ONION;
|
||||||
|
} else {
|
||||||
|
c.m_network = NET_IPV4;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/*protected_peer_ids=*/{0, 1, 6},
|
||||||
|
/*unprotected_peer_ids=*/{2, 3, 4, 5},
|
||||||
|
random_context));
|
||||||
|
|
||||||
|
// Combined test: expect having 1 CJDNS, 1 I2P, 1 localhost and 1 onion peer
|
||||||
|
// out of 8 to protect 1 CJDNS, 1 I2P, 0 localhost, 0 onion and 2 other
|
||||||
|
// peers (4 total) sorted by longest uptime; stable sort breaks tie with
|
||||||
|
// array order of CJDNS first.
|
||||||
|
BOOST_CHECK(IsProtected(
|
||||||
|
8, [](NodeEvictionCandidate& c) {
|
||||||
|
c.nTimeConnected = c.id;
|
||||||
|
c.m_is_local = (c.id == 3);
|
||||||
|
if (c.id == 5) {
|
||||||
|
c.m_network = NET_CJDNS;
|
||||||
|
} else if (c.id == 6) {
|
||||||
|
c.m_network = NET_I2P;
|
||||||
|
} else if (c.id == 3) {
|
||||||
|
c.m_network = NET_ONION;
|
||||||
|
} else {
|
||||||
|
c.m_network = NET_IPV6;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/*protected_peer_ids=*/{0, 1, 5, 6},
|
||||||
|
/*unprotected_peer_ids=*/{2, 3, 4, 7},
|
||||||
|
random_context));
|
||||||
|
|
||||||
|
// Combined test: expect having 2 CJDNS, 2 I2P, 4 localhost, and 2 onion
|
||||||
|
// peers out of 16 to protect 1 CJDNS, 1 I2P, 1 localhost, 1 onion (4/16
|
||||||
|
// total), plus 4 others for 8 total, sorted by longest uptime.
|
||||||
|
BOOST_CHECK(IsProtected(
|
||||||
|
16, [](NodeEvictionCandidate& c) {
|
||||||
|
c.nTimeConnected = c.id;
|
||||||
|
c.m_is_local = (c.id > 5);
|
||||||
|
if (c.id == 11 || c.id == 15) {
|
||||||
|
c.m_network = NET_CJDNS;
|
||||||
|
} else if (c.id == 10 || c.id == 14) {
|
||||||
|
c.m_network = NET_I2P;
|
||||||
|
} else if (c.id == 8 || c.id == 9) {
|
||||||
|
c.m_network = NET_ONION;
|
||||||
|
} else {
|
||||||
|
c.m_network = NET_IPV4;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/*protected_peer_ids=*/{0, 1, 2, 3, 6, 8, 10, 11},
|
||||||
|
/*unprotected_peer_ids=*/{4, 5, 7, 9, 12, 13, 14, 15},
|
||||||
|
random_context));
|
||||||
|
|
||||||
|
// Combined test: expect having 6 CJDNS, 1 I2P, 1 localhost, and 4 onion
|
||||||
|
// peers out of 24 to protect 2 CJDNS, 1 I2P, 1 localhost, and 2 onions (6
|
||||||
|
// total), plus 6 others for 12/24 total, sorted by longest uptime.
|
||||||
|
BOOST_CHECK(IsProtected(
|
||||||
|
24, [](NodeEvictionCandidate& c) {
|
||||||
|
c.nTimeConnected = c.id;
|
||||||
|
c.m_is_local = (c.id == 13);
|
||||||
|
if (c.id > 17) {
|
||||||
|
c.m_network = NET_CJDNS;
|
||||||
|
} else if (c.id == 17) {
|
||||||
|
c.m_network = NET_I2P;
|
||||||
|
} else if (c.id == 12 || c.id == 14 || c.id == 15 || c.id == 16) {
|
||||||
|
c.m_network = NET_ONION;
|
||||||
|
} else {
|
||||||
|
c.m_network = NET_IPV6;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/*protected_peer_ids=*/{0, 1, 2, 3, 4, 5, 12, 13, 14, 17, 18, 19},
|
||||||
|
/*unprotected_peer_ids=*/{6, 7, 8, 9, 10, 11, 15, 16, 20, 21, 22, 23},
|
||||||
|
random_context));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if any of the node ids in node_ids are selected for eviction.
|
// Returns true if any of the node ids in node_ids are selected for eviction.
|
||||||
|
Loading…
Reference in New Issue
Block a user