From 1e15acf478ae071234350c9b38dc823dfe2e3419 Mon Sep 17 00:00:00 2001 From: Jon Atack Date: Tue, 20 Apr 2021 13:22:20 +0200 Subject: p2p: make ProtectEvictionCandidatesByRatio() fully ratio-based with a more abstract framework to allow easily extending inbound eviction protection to peers connected through new higher-latency networks that are disadvantaged by our inbound eviction criteria, such as I2P and perhaps other BIP155 networks in the future like CJDNS. This is a change in behavior. The algorithm is a basically a multi-pass knapsack: - Count the number of eviction candidates in each of the disadvantaged privacy networks. - Sort the networks from lower to higher candidate counts, so that a network with fewer candidates will have the first opportunity for any unused slots remaining from the previous iteration. In the case of a tie in candidate counts, priority is given by array member order from first to last, guesstimated to favor more unusual networks. - Iterate through the networks in this order. On each iteration, allocate each network an equal number of protected slots targeting a total number of candidates to protect, provided any slots remain in the knapsack. - Protect the candidates in that network having the longest uptime, if any in that network are present. - Continue iterating as long as we have non-allocated slots remaining and candidates available to protect. Localhost peers are treated as a network like Tor or I2P by aliasing them to an unused Network enumerator: Network::NET_MAX. The goal is to favorise diversity of our inbound connections. Credit to Vasil Dimov for improving the algorithm from single-pass to multi-pass to better allocate unused protection slots. Co-authored-by: Vasil Dimov --- src/test/net_peer_eviction_tests.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'src/test') diff --git a/src/test/net_peer_eviction_tests.cpp b/src/test/net_peer_eviction_tests.cpp index 9e5b4a47d5..7dc2f2562a 100644 --- a/src/test/net_peer_eviction_tests.cpp +++ b/src/test/net_peer_eviction_tests.cpp @@ -93,6 +93,7 @@ BOOST_AUTO_TEST_CASE(peer_protection_test) num_peers, [](NodeEvictionCandidate& c) { c.nTimeConnected = c.id; c.m_is_onion = c.m_is_local = false; + c.m_network = NET_IPV4; }, /* protected_peer_ids */ {0, 1, 2, 3, 4, 5}, /* unprotected_peer_ids */ {6, 7, 8, 9, 10, 11}, @@ -103,6 +104,7 @@ BOOST_AUTO_TEST_CASE(peer_protection_test) num_peers, [num_peers](NodeEvictionCandidate& c) { c.nTimeConnected = num_peers - c.id; c.m_is_onion = c.m_is_local = false; + c.m_network = NET_IPV6; }, /* protected_peer_ids */ {6, 7, 8, 9, 10, 11}, /* unprotected_peer_ids */ {0, 1, 2, 3, 4, 5}, @@ -111,22 +113,23 @@ BOOST_AUTO_TEST_CASE(peer_protection_test) // Test protection of onion and localhost peers... // Expect 1/4 onion peers to be protected from eviction, - // independently of other characteristics. + // if no localhost peers. BOOST_CHECK(IsProtected( num_peers, [](NodeEvictionCandidate& c) { - c.m_is_onion = (c.id == 3 || c.id == 8 || c.id == 9); + c.m_is_local = false; + c.m_network = (c.id == 3 || c.id == 8 || c.id == 9) ? NET_ONION : NET_IPV4; }, /* protected_peer_ids */ {3, 8, 9}, /* unprotected_peer_ids */ {}, random_context)); - // Expect 1/4 onion peers and 1/4 of the others to be protected - // from eviction, sorted by longest uptime (lowest nTimeConnected). + // 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. BOOST_CHECK(IsProtected( num_peers, [](NodeEvictionCandidate& c) { c.nTimeConnected = c.id; c.m_is_local = false; - c.m_is_onion = (c.id == 3 || c.id > 7); + c.m_network = (c.id == 3 || c.id > 7) ? NET_ONION : NET_IPV6; }, /* protected_peer_ids */ {0, 1, 2, 3, 8, 9}, /* unprotected_peer_ids */ {4, 5, 6, 7, 10, 11}, @@ -138,6 +141,7 @@ BOOST_AUTO_TEST_CASE(peer_protection_test) num_peers, [](NodeEvictionCandidate& c) { c.m_is_onion = false; c.m_is_local = (c.id == 1 || c.id == 9 || c.id == 11); + c.m_network = NET_IPV4; }, /* protected_peer_ids */ {1, 9, 11}, /* unprotected_peer_ids */ {}, @@ -150,6 +154,7 @@ BOOST_AUTO_TEST_CASE(peer_protection_test) c.nTimeConnected = c.id; c.m_is_onion = false; c.m_is_local = (c.id > 6); + c.m_network = NET_IPV6; }, /* protected_peer_ids */ {0, 1, 2, 7, 8, 9}, /* unprotected_peer_ids */ {3, 4, 5, 6, 10, 11}, -- cgit v1.2.3