Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change fanout to scale by std::log rather than std::sqrt #4835

Merged
merged 2 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions nano/core_test/peer_container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,8 @@ TEST (peer_container, DISABLED_list_fanout)
nano::test::system system{ 1 };
auto node = system.nodes[0];
ASSERT_EQ (0, node->network.size ());
ASSERT_EQ (0.0, node->network.size_sqrt ());
ASSERT_EQ (0, node->network.fanout ());
ASSERT_EQ (0.0f, node->network.size_log ());
ASSERT_EQ (1, node->network.fanout ());
ASSERT_TRUE (node->network.list (node->network.fanout ()).empty ());

auto add_peer = [&node, &system] () {
Expand All @@ -185,26 +185,27 @@ TEST (peer_container, DISABLED_list_fanout)

add_peer ();
ASSERT_TIMELY_EQ (5s, 1, node->network.size ());
ASSERT_EQ (1.f, node->network.size_sqrt ());
ASSERT_EQ (0.0f, node->network.size_log ());
ASSERT_EQ (1, node->network.fanout ());
ASSERT_EQ (1, node->network.list (node->network.fanout ()).size ());

add_peer ();
ASSERT_TIMELY_EQ (5s, 2, node->network.size ());
ASSERT_EQ (std::sqrt (2.f), node->network.size_sqrt ());
add_peer ();
ASSERT_TIMELY_EQ (5s, 3, node->network.size ());
ASSERT_EQ (std::log (3.0f), node->network.size_log ());
ASSERT_EQ (2, node->network.fanout ());
ASSERT_EQ (2, node->network.list (node->network.fanout ()).size ());

unsigned number_of_peers = 10;
for (unsigned i = 2; i < number_of_peers; ++i)
for (unsigned i = 3; i < number_of_peers; ++i)
{
add_peer ();
}

ASSERT_TIMELY_EQ (5s, number_of_peers, node->network.size ());
ASSERT_EQ (std::sqrt (float (number_of_peers)), node->network.size_sqrt ());
ASSERT_EQ (4, node->network.fanout ());
ASSERT_EQ (4, node->network.list (node->network.fanout ()).size ());
ASSERT_EQ (std::log (float (number_of_peers)), node->network.size_log ());
ASSERT_EQ (3, node->network.fanout ());
ASSERT_EQ (3, node->network.list (node->network.fanout ()).size ());
}

// Test to make sure we don't repeatedly send keepalive messages to nodes that aren't responding
Expand Down
10 changes: 6 additions & 4 deletions nano/node/network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,8 @@ std::deque<std::shared_ptr<nano::transport::channel>> nano::network::list_non_pr
// Simulating with sqrt_broadcast_simulate shows we only need to broadcast to sqrt(total_peers) random peers in order to successfully publish to everyone with high probability
Copy link
Contributor

@not-Ian not-Ian Jan 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this comment out of date after this change?

sqrt(total_peers) should now be log(total_peers), no?

std::size_t nano::network::fanout (float scale) const
{
return static_cast<std::size_t> (std::ceil (scale * size_sqrt ()));
auto fanout_l = std::max (2.0f, size_log ());
return static_cast<std::size_t> (std::ceil (scale * fanout_l));
}

std::unordered_set<std::shared_ptr<nano::transport::channel>> nano::network::random_set (std::size_t max_count, uint8_t minimum_version) const
Expand Down Expand Up @@ -519,9 +520,10 @@ std::size_t nano::network::size () const
return tcp_channels.size ();
}

float nano::network::size_sqrt () const
float nano::network::size_log () const
{
return static_cast<float> (std::sqrt (size ()));
auto size_l = std::max (static_cast<size_t> (1u), size ()); // Clamp size to domain of std::log
return static_cast<float> (std::log (size_l));
}

bool nano::network::empty () const
Expand Down Expand Up @@ -735,4 +737,4 @@ nano::container_info nano::syn_cookies::container_info () const
info.put ("syn_cookies", cookies.size ());
info.put ("syn_cookies_per_ip", cookies_per_ip.size ());
return info;
}
}
2 changes: 1 addition & 1 deletion nano/node/network.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ class network final
nano::tcp_endpoint bootstrap_peer ();
void cleanup (std::chrono::steady_clock::time_point const & cutoff);
std::size_t size () const;
float size_sqrt () const;
float size_log () const;
bool empty () const;
void erase (nano::transport::channel const &);
/** Disconnects and adds peer to exclusion list */
Expand Down
Loading