80 lines
2.2 KiB
C++
80 lines
2.2 KiB
C++
#include <nano/node/confirmation_solicitor.hpp>
|
|
#include <nano/node/election.hpp>
|
|
|
|
using namespace std::chrono_literals;
|
|
|
|
nano::confirmation_solicitor::confirmation_solicitor (nano::network & network_a, nano::network_constants const & params_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),
|
|
network (network_a)
|
|
{
|
|
}
|
|
|
|
void nano::confirmation_solicitor::prepare (std::vector<nano::representative> const & representatives_a)
|
|
{
|
|
assert (!prepared);
|
|
requests.clear ();
|
|
rebroadcasted = 0;
|
|
representatives = representatives_a;
|
|
prepared = true;
|
|
}
|
|
|
|
bool nano::confirmation_solicitor::broadcast (nano::election const & election_a)
|
|
{
|
|
assert (prepared);
|
|
bool result (true);
|
|
if (rebroadcasted++ < max_block_broadcasts)
|
|
{
|
|
network.flood_block (election_a.status.winner);
|
|
result = false;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
bool nano::confirmation_solicitor::add (nano::election const & election_a)
|
|
{
|
|
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 ()), n (representatives.end ()); i != n && count < max_election_requests; ++i)
|
|
{
|
|
auto rep (*i);
|
|
if (election_a.last_votes.find (rep.account) == election_a.last_votes.end ())
|
|
{
|
|
auto & request_queue (requests[rep.channel]);
|
|
if (request_queue.size () < max_channel_requests)
|
|
{
|
|
request_queue.emplace_back (election_a.status.winner->hash (), election_a.status.winner->root ());
|
|
++count;
|
|
}
|
|
}
|
|
}
|
|
return count == 0;
|
|
}
|
|
|
|
void nano::confirmation_solicitor::flush ()
|
|
{
|
|
assert (prepared);
|
|
for (auto const & request_queue : requests)
|
|
{
|
|
auto const & channel (request_queue.first);
|
|
std::vector<std::pair<nano::block_hash, nano::root>> roots_hashes_l;
|
|
for (auto const & root_hash : request_queue.second)
|
|
{
|
|
roots_hashes_l.push_back (root_hash);
|
|
if (roots_hashes_l.size () == nano::network::confirm_req_hashes_max)
|
|
{
|
|
nano::confirm_req req (roots_hashes_l);
|
|
channel->send (req);
|
|
roots_hashes_l.clear ();
|
|
}
|
|
}
|
|
if (!roots_hashes_l.empty ())
|
|
{
|
|
nano::confirm_req req (roots_hashes_l);
|
|
channel->send (req);
|
|
}
|
|
}
|
|
prepared = false;
|
|
}
|