Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F13115603
D9676.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
4 KB
Subscribers
None
D9676.diff
View Options
diff --git a/src/net.cpp b/src/net.cpp
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -848,6 +848,7 @@
CAddress addr;
uint64_t nKeyedNetGroup;
bool prefer_evict;
+ bool m_is_local;
};
static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a,
@@ -860,6 +861,15 @@
return a.nTimeConnected > b.nTimeConnected;
}
+static bool CompareLocalHostTimeConnected(const NodeEvictionCandidate &a,
+ const NodeEvictionCandidate &b) {
+ if (a.m_is_local != b.m_is_local) {
+ return b.m_is_local;
+ }
+
+ return a.nTimeConnected > b.nTimeConnected;
+}
+
static bool CompareNetGroupKeyed(const NodeEvictionCandidate &a,
const NodeEvictionCandidate &b) {
return a.nKeyedNetGroup < b.nKeyedNetGroup;
@@ -899,6 +909,25 @@
return a.nTimeConnected > b.nTimeConnected;
}
+// Pick out the potential block-relay only peers, and sort them by last block
+// time.
+static bool CompareNodeBlockRelayOnlyTime(const NodeEvictionCandidate &a,
+ const NodeEvictionCandidate &b) {
+ if (a.fRelayTxes != b.fRelayTxes) {
+ return a.fRelayTxes;
+ }
+
+ if (a.nLastBlockTime != b.nLastBlockTime) {
+ return a.nLastBlockTime < b.nLastBlockTime;
+ }
+
+ if (a.fRelevantServices != b.fRelevantServices) {
+ return b.fRelevantServices;
+ }
+
+ return a.nTimeConnected > b.nTimeConnected;
+}
+
//! Sort an array by the specified comparator, then erase the last K elements.
template <typename T, typename Comparator>
static void EraseLastKElements(std::vector<T> &elements, Comparator comparator,
@@ -950,7 +979,8 @@
peer_filter_not_null,
node->addr,
node->nKeyedNetGroup,
- node->m_prefer_evict};
+ node->m_prefer_evict,
+ node->addr.IsLocal()};
vEvictionCandidates.push_back(candidate);
}
}
@@ -968,14 +998,46 @@
// into our mempool. An attacker cannot manipulate this metric without
// performing useful work.
EraseLastKElements(vEvictionCandidates, CompareNodeTXTime, 4);
+ // Protect up to 8 non-tx-relay peers that have sent us novel blocks.
+ std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(),
+ CompareNodeBlockRelayOnlyTime);
+ size_t erase_size = std::min(size_t(8), vEvictionCandidates.size());
+ vEvictionCandidates.erase(
+ std::remove_if(vEvictionCandidates.end() - erase_size,
+ vEvictionCandidates.end(),
+ [](NodeEvictionCandidate const &n) {
+ return !n.fRelayTxes && n.fRelevantServices;
+ }),
+ vEvictionCandidates.end());
+
// Protect 4 nodes that most recently sent us novel blocks.
// An attacker cannot manipulate this metric without performing useful work.
EraseLastKElements(vEvictionCandidates, CompareNodeBlockTime, 4);
+
// 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.
+ // Reserve half of these protected spots for localhost peers, even if
+ // they're not longest-uptime overall. This helps protect tor peers, which
+ // tend to be otherwise disadvantaged under our eviction criteria.
+ size_t initial_size = vEvictionCandidates.size();
+ size_t total_protect_size = initial_size / 2;
+
+ // Pick out up to 1/4 peers that are localhost, sorted by longest uptime.
+ std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(),
+ CompareLocalHostTimeConnected);
+ size_t local_erase_size = total_protect_size / 2;
+ vEvictionCandidates.erase(
+ std::remove_if(
+ vEvictionCandidates.end() - local_erase_size,
+ vEvictionCandidates.end(),
+ [](NodeEvictionCandidate const &n) { return n.m_is_local; }),
+ vEvictionCandidates.end());
+ // Calculate how many we removed, and update our total number of peers that
+ // we want to protect based on uptime accordingly.
+ total_protect_size -= initial_size - vEvictionCandidates.size();
EraseLastKElements(vEvictionCandidates, ReverseCompareNodeTimeConnected,
- vEvictionCandidates.size() / 2);
+ total_protect_size);
if (vEvictionCandidates.empty()) {
return false;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Mar 1, 11:31 (8 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5187622
Default Alt Text
D9676.diff (4 KB)
Attached To
D9676: Protect localhost and block-relay-only peers from eviction
Event Timeline
Log In to Comment