Changeset View
Changeset View
Standalone View
Standalone View
src/net.cpp
Show First 20 Lines • Show All 941 Lines • ▼ Show 20 Lines | static bool CompareNodeAvailabilityScore(const NodeEvictionCandidate &a, | ||||
} | } | ||||
return a.nTimeConnected > b.nTimeConnected; | return a.nTimeConnected > b.nTimeConnected; | ||||
} | } | ||||
static void | static void | ||||
ProtectAvalancheNodes(std::vector<NodeEvictionCandidate> &candidates) { | ProtectAvalancheNodes(std::vector<NodeEvictionCandidate> &candidates) { | ||||
std::map<PeerId, NodeEvictionCandidate> preferredNodes; | std::map<PeerId, NodeEvictionCandidate> preferredNodes; | ||||
uint64_t minimalPeerScore = 0; | |||||
for (auto &c : candidates) { | for (auto &c : candidates) { | ||||
if (!c.fAvalanche || c.peerid == NO_PEER) { | if (!c.fAvalanche || c.peerid == NO_PEER) { | ||||
continue; | continue; | ||||
} | } | ||||
auto handle = preferredNodes.extract(c.peerid); | auto handle = preferredNodes.extract(c.peerid); | ||||
if (!handle) { | if (!handle) { | ||||
// Count the score once per peer | |||||
minimalPeerScore += c.peerScore; | |||||
preferredNodes.emplace(c.peerid, c); | preferredNodes.emplace(c.peerid, c); | ||||
continue; | continue; | ||||
} | } | ||||
auto &mappedCandidate = handle.mapped(); | auto &mappedCandidate = handle.mapped(); | ||||
if (c.availabilityScore > mappedCandidate.availabilityScore) { | if (c.availabilityScore > mappedCandidate.availabilityScore) { | ||||
mappedCandidate = c; | mappedCandidate = c; | ||||
} | } | ||||
preferredNodes.insert(std::move(handle)); | preferredNodes.insert(std::move(handle)); | ||||
} | } | ||||
// Remove the nodes while keeping the ordering of the other elements | // Remove the nodes while keeping the ordering of the other elements, unless | ||||
// the peer has less than ~0.1% chance of being selected for polling. | |||||
minimalPeerScore /= 1000; | |||||
for (auto cit = candidates.begin(); cit != candidates.end();) { | for (auto cit = candidates.begin(); cit != candidates.end();) { | ||||
auto nit = preferredNodes.find(cit->peerid); | auto nit = preferredNodes.find(cit->peerid); | ||||
if (nit != preferredNodes.end() && nit->second.id == cit->id) { | if (nit != preferredNodes.end() && nit->second.id == cit->id && | ||||
cit->peerScore >= minimalPeerScore) { | |||||
cit = candidates.erase(cit); | cit = candidates.erase(cit); | ||||
} else { | } else { | ||||
++cit; | ++cit; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
//! Sort an array by the specified comparator, then erase the last K elements. | //! Sort an array by the specified comparator, then erase the last K elements. | ||||
▲ Show 20 Lines • Show All 149 Lines • ▼ Show 20 Lines | std::vector<NodeEvictionCandidate> vEvictionCandidates; | ||||
if (node->m_tx_relay != nullptr) { | if (node->m_tx_relay != nullptr) { | ||||
LOCK(node->m_tx_relay->cs_filter); | LOCK(node->m_tx_relay->cs_filter); | ||||
peer_relay_txes = node->m_tx_relay->fRelayTxes; | peer_relay_txes = node->m_tx_relay->fRelayTxes; | ||||
peer_filter_not_null = node->m_tx_relay->pfilter != nullptr; | peer_filter_not_null = node->m_tx_relay->pfilter != nullptr; | ||||
} | } | ||||
double availabilityScore = std::numeric_limits<double>::lowest(); | double availabilityScore = std::numeric_limits<double>::lowest(); | ||||
PeerId peerid = NO_PEER; | PeerId peerid = NO_PEER; | ||||
uint32_t peerScore = 0; | |||||
bool fAvalanche = node->m_avalanche_state != nullptr; | bool fAvalanche = node->m_avalanche_state != nullptr; | ||||
if (fAvalanche) { | if (fAvalanche) { | ||||
availabilityScore = | availabilityScore = | ||||
node->m_avalanche_state->getAvailabilityScore(); | node->m_avalanche_state->getAvailabilityScore(); | ||||
g_avalanche->withPeerManager( | g_avalanche->withPeerManager( | ||||
[&node, &peerid](const avalanche::PeerManager &pm) { | [&node, &peerid, | ||||
pm.forNode(node->GetId(), | &peerScore](const avalanche::PeerManager &pm) { | ||||
if (pm.forNode(node->GetId(), | |||||
[&peerid](const avalanche::Node &n) { | [&peerid](const avalanche::Node &n) { | ||||
peerid = n.peerid; | peerid = n.peerid; | ||||
return true; | return true; | ||||
})) { | |||||
pm.forPeer(peerid, | |||||
[&peerScore](const avalanche::Peer &p) { | |||||
peerScore = p.getScore(); | |||||
return true; | |||||
}); | }); | ||||
} | |||||
}); | }); | ||||
} | } | ||||
NodeEvictionCandidate candidate = { | NodeEvictionCandidate candidate = { | ||||
node->GetId(), | node->GetId(), | ||||
node->nTimeConnected, | node->nTimeConnected, | ||||
node->nMinPingUsecTime, | node->nMinPingUsecTime, | ||||
node->nLastBlockTime, | node->nLastBlockTime, | ||||
node->nLastProofTime, | node->nLastProofTime, | ||||
node->nLastTXTime, | node->nLastTXTime, | ||||
HasAllDesirableServiceFlags(node->nServices), | HasAllDesirableServiceFlags(node->nServices), | ||||
peer_relay_txes, | peer_relay_txes, | ||||
peer_filter_not_null, | peer_filter_not_null, | ||||
node->nKeyedNetGroup, | node->nKeyedNetGroup, | ||||
node->m_prefer_evict, | node->m_prefer_evict, | ||||
node->addr.IsLocal(), | node->addr.IsLocal(), | ||||
fAvalanche, | fAvalanche, | ||||
availabilityScore, | availabilityScore, | ||||
peerid, | peerid, | ||||
peerScore, | |||||
}; | }; | ||||
vEvictionCandidates.push_back(candidate); | vEvictionCandidates.push_back(candidate); | ||||
} | } | ||||
} | } | ||||
const std::optional<NodeId> node_id_to_evict = | const std::optional<NodeId> node_id_to_evict = | ||||
SelectNodeToEvict(std::move(vEvictionCandidates)); | SelectNodeToEvict(std::move(vEvictionCandidates)); | ||||
if (!node_id_to_evict) { | if (!node_id_to_evict) { | ||||
return false; | return false; | ||||
▲ Show 20 Lines • Show All 2,165 Lines • Show Last 20 Lines |