mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-14 12:43:40 +02:00
Merge 69a13eb246 into merged_master (Bitcoin PR #19670)
This commit is contained in:
commit
dfd4a46a05
1 changed files with 36 additions and 2 deletions
38
src/net.cpp
38
src/net.cpp
|
|
@ -816,6 +816,7 @@ struct NodeEvictionCandidate
|
|||
CAddress addr;
|
||||
uint64_t nKeyedNetGroup;
|
||||
bool prefer_evict;
|
||||
bool m_is_local;
|
||||
};
|
||||
|
||||
static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
|
||||
|
|
@ -828,6 +829,12 @@ static bool ReverseCompareNodeTimeConnected(const NodeEvictionCandidate &a, cons
|
|||
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;
|
||||
}
|
||||
|
|
@ -849,6 +856,14 @@ static bool CompareNodeTXTime(const NodeEvictionCandidate &a, const NodeEviction
|
|||
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>
|
||||
|
|
@ -891,7 +906,7 @@ bool CConnman::AttemptToEvictConnection()
|
|||
node->nLastBlockTime, node->nLastTXTime,
|
||||
HasAllDesirableServiceFlags(node->nServices),
|
||||
peer_relay_txes, peer_filter_not_null, node->addr, node->nKeyedNetGroup,
|
||||
node->m_prefer_evict};
|
||||
node->m_prefer_evict, node->addr.IsLocal()};
|
||||
vEvictionCandidates.push_back(candidate);
|
||||
}
|
||||
}
|
||||
|
|
@ -907,12 +922,31 @@ bool CConnman::AttemptToEvictConnection()
|
|||
// Protect 4 nodes that most recently sent us novel transactions accepted 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.
|
||||
EraseLastKElements(vEvictionCandidates, ReverseCompareNodeTimeConnected, vEvictionCandidates.size() / 2);
|
||||
// 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, total_protect_size);
|
||||
|
||||
if (vEvictionCandidates.empty()) return false;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue