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

Directed block broadcasting for long elections #2505

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
10 changes: 5 additions & 5 deletions nano/core_test/active_transactions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -590,11 +590,7 @@ TEST (active_transactions, update_difficulty)
node1.process_active (send1);
node1.process_active (send2);
node1.block_processor.flush ();
system.deadline_set (10s);
while (node1.active.size () != 2 || node2.active.size () != 2)
{
ASSERT_NO_ERROR (system.poll ());
}
ASSERT_NO_ERROR (system.poll_until_true (10s, [&node1, &node2] { return node1.active.size () == 2 && node2.active.size () == 2; }));
// Update work with higher difficulty
auto work1 = node1.work_generate_blocking (send1->root (), difficulty1 + 1);
auto work2 = node1.work_generate_blocking (send2->root (), difficulty2 + 1);
Expand All @@ -609,6 +605,10 @@ TEST (active_transactions, update_difficulty)
node1.process_active (send1);
node1.process_active (send2);
node1.block_processor.flush ();
// Share the updated blocks
node1.network.flood_block (send1);
node1.network.flood_block (send2);

system.deadline_set (10s);
bool done (false);
while (!done)
Expand Down
29 changes: 22 additions & 7 deletions nano/node/confirmation_solicitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ nano::confirmation_solicitor::confirmation_solicitor (nano::network & network_a,
max_confirm_req_batches (params_a.is_test_network () ? 1 : 20),
max_block_broadcasts (params_a.is_test_network () ? 4 : 30),
max_election_requests (30),
max_election_broadcasts (network_a.fanout () / 2),
network (network_a)
{
}
Expand All @@ -16,28 +17,42 @@ void nano::confirmation_solicitor::prepare (std::vector<nano::representative> co
debug_assert (!prepared);
requests.clear ();
rebroadcasted = 0;
representatives = representatives_a;
/** Two copies are required as representatives can be erased from \p representatives_requests */
representatives_requests = representatives_a;
representatives_broadcasts = representatives_a;
prepared = true;
}

bool nano::confirmation_solicitor::broadcast (nano::election const & election_a)
{
debug_assert (prepared);
bool result (true);
bool error (true);
if (rebroadcasted++ < max_block_broadcasts)
{
network.flood_block (election_a.status.winner);
result = false;
nano::publish winner (election_a.status.winner);
unsigned count = 0;
// Directed broadcasting to principal representatives
for (auto i (representatives_broadcasts.begin ()), n (representatives_broadcasts.end ()); i != n && count < max_election_broadcasts; ++i)
{
if (election_a.last_votes.find (i->account) == election_a.last_votes.end ())
{
i->channel->send (winner);
++count;
}
}
// Random flood for block propagation
network.flood_message (winner, nano::buffer_drop_policy::limiter, 0.5f);
error = false;
}
return result;
return error;
}

bool nano::confirmation_solicitor::add (nano::election const & election_a)
{
debug_assert (prepared);
auto const max_channel_requests (max_confirm_req_batches * nano::network::confirm_req_hashes_max);
unsigned count = 0;
for (auto i (representatives.begin ()); i != representatives.end () && count < max_election_requests;)
for (auto i (representatives_requests.begin ()); i != representatives_requests.end () && count < max_election_requests;)
{
bool full_queue (false);
auto rep (*i);
Expand All @@ -54,7 +69,7 @@ bool nano::confirmation_solicitor::add (nano::election const & election_a)
full_queue = true;
}
}
i = !full_queue ? i + 1 : representatives.erase (i);
i = !full_queue ? i + 1 : representatives_requests.erase (i);
}
return count == 0;
}
Expand Down
5 changes: 4 additions & 1 deletion nano/node/confirmation_solicitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,15 @@ class confirmation_solicitor final
size_t const max_block_broadcasts;
/** Maximum amount of requests to be sent per election */
size_t const max_election_requests;
/** Maximum amount of directed broadcasts to be sent per election */
size_t const max_election_broadcasts;

private:
nano::network & network;

unsigned rebroadcasted{ 0 };
std::vector<nano::representative> representatives;
std::vector<nano::representative> representatives_requests;
std::vector<nano::representative> representatives_broadcasts;
using vector_root_hashes = std::vector<std::pair<nano::block_hash, nano::root>>;
std::unordered_map<std::shared_ptr<nano::transport::channel>, vector_root_hashes> requests;
bool prepared{ false };
Expand Down
4 changes: 2 additions & 2 deletions nano/node/network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,9 @@ void nano::network::send_node_id_handshake (std::shared_ptr<nano::transport::cha
channel_a->send (message);
}

void nano::network::flood_message (nano::message const & message_a, nano::buffer_drop_policy drop_policy_a)
void nano::network::flood_message (nano::message const & message_a, nano::buffer_drop_policy const drop_policy_a, float const scale_a)
{
for (auto & i : list (fanout ()))
for (auto & i : list (fanout (scale_a)))
{
i->send (message_a, nullptr, drop_policy_a);
}
Expand Down
2 changes: 1 addition & 1 deletion nano/node/network.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class network final
~network ();
void start ();
void stop ();
void flood_message (nano::message const &, nano::buffer_drop_policy = nano::buffer_drop_policy::limiter);
void flood_message (nano::message const &, nano::buffer_drop_policy const = nano::buffer_drop_policy::limiter, float const = 1.0f);
void flood_keepalive ()
{
nano::keepalive message;
Expand Down