dncurrency/nano/node/peer_exclusion.cpp
Piotr Wójcik baabcca426
Telemetry refactor (#4026)
* Simplify telemetry

* Fix tests

* Cleanup config

* Cleanup local telemetry

* Remove unused flag

* Fix slow tests

* Fix rpc tests

* Cleanup `nano::test::compare_telemetry`

* Add more testcases

* Add ongoing telemetry broadcasts

* Cleanup

* Fixes

* Do not immediately remove telemetry from disconnected peers

* Increase telemetry broadcast & request intervals

* Update docs

* Refactor `peer_exclusion` a bit

* Filter and disconnect from peers with mismatched genesis

---------

Co-authored-by: clemahieu <clemahieu@gmail.com>
2023-02-02 16:14:26 +01:00

102 lines
3.1 KiB
C++

#include <nano/node/peer_exclusion.hpp>
nano::peer_exclusion::peer_exclusion (std::size_t max_size_a) :
max_size{ max_size_a }
{
}
uint64_t nano::peer_exclusion::add (nano::tcp_endpoint const & endpoint)
{
uint64_t result = 0;
nano::lock_guard<nano::mutex> guard{ mutex };
if (auto existing = peers.get<tag_endpoint> ().find (endpoint.address ()); existing == peers.get<tag_endpoint> ().end ())
{
// Clean old excluded peers
while (peers.size () > 1 && peers.size () >= max_size)
{
peers.get<tag_exclusion> ().erase (peers.get<tag_exclusion> ().begin ());
}
debug_assert (peers.size () <= max_size);
// Insert new endpoint
auto inserted = peers.insert (peer_exclusion::item{ std::chrono::steady_clock::steady_clock::now () + exclude_time_hours, endpoint.address (), 1 });
(void)inserted;
debug_assert (inserted.second);
result = 1;
}
else
{
// Update existing endpoint
peers.get<tag_endpoint> ().modify (existing, [&result] (peer_exclusion::item & item_a) {
++item_a.score;
result = item_a.score;
if (item_a.score == peer_exclusion::score_limit)
{
item_a.exclude_until = std::chrono::steady_clock::now () + peer_exclusion::exclude_time_hours;
}
else if (item_a.score > peer_exclusion::score_limit)
{
item_a.exclude_until = std::chrono::steady_clock::now () + peer_exclusion::exclude_time_hours * item_a.score * 2;
}
});
}
return result;
}
uint64_t nano::peer_exclusion::score (const nano::tcp_endpoint & endpoint) const
{
nano::lock_guard<nano::mutex> guard{ mutex };
if (auto existing = peers.get<tag_endpoint> ().find (endpoint.address ()); existing != peers.get<tag_endpoint> ().end ())
{
return existing->score;
}
return 0;
}
std::chrono::steady_clock::time_point nano::peer_exclusion::until (const nano::tcp_endpoint & endpoint) const
{
nano::lock_guard<nano::mutex> guard{ mutex };
if (auto existing = peers.get<tag_endpoint> ().find (endpoint.address ()); existing != peers.get<tag_endpoint> ().end ())
{
return existing->exclude_until;
}
return {};
}
bool nano::peer_exclusion::check (nano::tcp_endpoint const & endpoint) const
{
nano::lock_guard<nano::mutex> guard{ mutex };
if (auto existing = peers.get<tag_endpoint> ().find (endpoint.address ()); existing != peers.get<tag_endpoint> ().end ())
{
if (existing->score >= score_limit && existing->exclude_until > std::chrono::steady_clock::now ())
{
return true;
}
}
return false;
}
void nano::peer_exclusion::remove (nano::tcp_endpoint const & endpoint_a)
{
nano::lock_guard<nano::mutex> guard{ mutex };
peers.get<tag_endpoint> ().erase (endpoint_a.address ());
}
std::size_t nano::peer_exclusion::size () const
{
nano::lock_guard<nano::mutex> guard{ mutex };
return peers.size ();
}
std::unique_ptr<nano::container_info_component> nano::peer_exclusion::collect_container_info (std::string const & name)
{
nano::lock_guard<nano::mutex> guard{ mutex };
auto composite = std::make_unique<container_info_composite> (name);
composite->add_component (std::make_unique<container_info_leaf> (container_info{ "peers", peers.size (), sizeof (decltype (peers)::value_type) }));
return composite;
}