Adding limiter to not bootstrap to clients don't respond.

This commit is contained in:
clemahieu 2015-08-31 02:01:53 -05:00
commit be90356269
3 changed files with 87 additions and 39 deletions

View file

@ -121,4 +121,17 @@ TEST (peer_container, fill_random_part)
ASSERT_TRUE (std::none_of (target.begin (), target.begin () + half, [] (rai::endpoint const & endpoint_a) {return endpoint_a == rai::endpoint (boost::asio::ip::address_v6::loopback (), 10000); }));
ASSERT_TRUE (std::none_of (target.begin (), target.begin () + half, [] (rai::endpoint const & endpoint_a) {return endpoint_a == rai::endpoint (boost::asio::ip::address_v6::loopback (), 0); }));
ASSERT_TRUE (std::all_of (target.begin () + half, target.end (), [] (rai::endpoint const & endpoint_a) {return endpoint_a == rai::endpoint (boost::asio::ip::address_v6::any (), 0); }));
}
TEST (peer_container, bootstrap_limit)
{
rai::peer_container peers (rai::endpoint {});
auto one (rai::endpoint (boost::asio::ip::address_v6::loopback(), 2048));
peers.insert (one);
auto list0 (peers.bootstrap_candidates ());
ASSERT_EQ (1, list0.size ());
ASSERT_EQ (one, list0 [0].endpoint);
peers.bootstrap_failed (one);
auto list1 (peers.bootstrap_candidates ());
ASSERT_EQ (0, list1.size ());
}

View file

@ -2369,6 +2369,21 @@ std::vector <rai::peer_information> rai::peer_container::list ()
return result;
}
std::vector <rai::peer_information> rai::peer_container::bootstrap_candidates ()
{
std::vector <rai::peer_information> result;
std::lock_guard <std::mutex> lock (mutex);
auto now (std::chrono::system_clock::now ());
for (auto i (peers.begin ()), j (peers.end ()); i != j; ++i)
{
if (now - i->last_bootstrap_failure > std::chrono::minutes (15))
{
result.push_back (*i);
}
}
return result;
}
void rai::publish::visit (rai::message_visitor & visitor_a) const
{
visitor_a.publish (*this);
@ -3836,7 +3851,7 @@ void rai::bootstrap_initiator::bootstrap (rai::endpoint const & endpoint_a)
void rai::bootstrap_initiator::bootstrap_any ()
{
auto list (node.peers.list ());
auto list (node.peers.bootstrap_candidates ());
if (!list.empty ())
{
bootstrap (list [random_pool.GenerateWord32 (0, list.size () - 1)].endpoint);
@ -4252,42 +4267,43 @@ void rai::bootstrap_client::run (boost::asio::ip::tcp::endpoint const & endpoint
BOOST_LOG (node->log) << boost::str (boost::format ("Initiating bootstrap connection to %1%") % endpoint_a);
}
auto this_l (shared_from_this ());
socket.async_connect (endpoint_a, [this_l] (boost::system::error_code const & ec)
socket.async_connect (endpoint_a, [this_l, endpoint_a] (boost::system::error_code const & ec)
{
this_l->connect_action (ec);
if (!ec)
{
this_l->connect_action ();
}
else
{
if (this_l->node->config.logging.network_logging ())
{
BOOST_LOG (this_l->node->log) << boost::str (boost::format ("Error initiating bootstrap connection %1%") % ec.message ());
}
this_l->node->peers.bootstrap_failed (rai::endpoint (endpoint_a.address (), endpoint_a.port ()));
}
});
}
void rai::bootstrap_client::connect_action (boost::system::error_code const & ec)
void rai::bootstrap_client::connect_action ()
{
if (!ec)
{
std::unique_ptr <rai::frontier_req> request (new rai::frontier_req);
request->start.clear ();
request->age = std::numeric_limits <decltype (request->age)>::max ();
request->count = std::numeric_limits <decltype (request->age)>::max ();
auto send_buffer (std::make_shared <std::vector <uint8_t>> ());
{
rai::vectorstream stream (*send_buffer);
request->serialize (stream);
}
if (node->config.logging.network_logging ())
{
BOOST_LOG (node->log) << boost::str (boost::format ("Initiating frontier request for %1% age %2% count %3%") % request->start.to_string () % request->age % request->count);
}
auto this_l (shared_from_this ());
boost::asio::async_write (socket, boost::asio::buffer (send_buffer->data (), send_buffer->size ()), [this_l, send_buffer] (boost::system::error_code const & ec, size_t size_a)
{
this_l->sent_request (ec, size_a);
});
}
else
{
if (node->config.logging.network_logging ())
{
BOOST_LOG (node->log) << boost::str (boost::format ("Error initiating bootstrap connection %1%") % ec.message ());
}
}
std::unique_ptr <rai::frontier_req> request (new rai::frontier_req);
request->start.clear ();
request->age = std::numeric_limits <decltype (request->age)>::max ();
request->count = std::numeric_limits <decltype (request->age)>::max ();
auto send_buffer (std::make_shared <std::vector <uint8_t>> ());
{
rai::vectorstream stream (*send_buffer);
request->serialize (stream);
}
if (node->config.logging.network_logging ())
{
BOOST_LOG (node->log) << boost::str (boost::format ("Initiating frontier request for %1% age %2% count %3%") % request->start.to_string () % request->age % request->count);
}
auto this_l (shared_from_this ());
boost::asio::async_write (socket, boost::asio::buffer (send_buffer->data (), send_buffer->size ()), [this_l, send_buffer] (boost::system::error_code const & ec, size_t size_a)
{
this_l->sent_request (ec, size_a);
});
}
void rai::bootstrap_client::sent_request (boost::system::error_code const & ec, size_t size_a)
@ -4671,6 +4687,19 @@ rai::bootstrap_server::~bootstrap_server ()
}
}
void rai::peer_container::bootstrap_failed (rai::endpoint const & endpoint_a)
{
std::lock_guard <std::mutex> lock (mutex);
auto existing (peers.find (endpoint_a));
if (existing != peers.end ())
{
peers.modify (existing, [] (rai::peer_information & info_a)
{
info_a.last_bootstrap_failure = std::chrono::system_clock::now ();
});
}
}
void rai::peer_container::random_fill (std::array <rai::endpoint, 8> & target_a)
{
auto peers (list ());
@ -4678,11 +4707,11 @@ void rai::peer_container::random_fill (std::array <rai::endpoint, 8> & target_a)
{
auto index (random_pool.GenerateWord32 (0, peers.size () - 1));
assert (index < peers.size ());
assert (index >= 0);
if (index != peers.size () - 1)
{
peers [index] = peers [peers.size () - 1];
}
assert (index >= 0);
if (index != peers.size () - 1)
{
peers [index] = peers [peers.size () - 1];
}
peers.pop_back ();
}
assert (peers.size () <= target_a.size ());
@ -4783,7 +4812,7 @@ bool rai::peer_container::insert (rai::endpoint const & endpoint_a, rai::block_h
}
else
{
peers.insert ({endpoint_a, std::chrono::system_clock::now (), std::chrono::system_clock::now (), hash_a});
peers.insert ({endpoint_a, std::chrono::system_clock::now (), std::chrono::system_clock::now (), std::chrono::system_clock::time_point (), hash_a});
unknown = true;
}
}

View file

@ -453,7 +453,7 @@ public:
bootstrap_client (std::shared_ptr <rai::node>, std::function <void ()> const & = [] () {});
~bootstrap_client ();
void run (rai::tcp_endpoint const &);
void connect_action (boost::system::error_code const &);
void connect_action ();
void sent_request (boost::system::error_code const &, size_t);
std::shared_ptr <rai::node> node;
boost::asio::ip::tcp::socket socket;
@ -526,6 +526,7 @@ public:
rai::endpoint endpoint;
std::chrono::system_clock::time_point last_contact;
std::chrono::system_clock::time_point last_attempt;
std::chrono::system_clock::time_point last_bootstrap_failure;
rai::block_hash most_recent;
};
class peer_container
@ -544,8 +545,13 @@ public:
bool insert (rai::endpoint const &, rai::block_hash const &);
// Does this peer probably know about this block
bool knows_about (rai::endpoint const &, rai::block_hash const &);
// Notify of bootstrap failure
void bootstrap_failed (rai::endpoint const &);
void random_fill (std::array <rai::endpoint, 8> &);
// List of all peers
std::vector <peer_information> list ();
// List of peers that haven't failed bootstrapping in a while
std::vector <peer_information> bootstrap_candidates ();
// Purge any peer where last_contact < time_point and return what was left
std::vector <rai::peer_information> purge_list (std::chrono::system_clock::time_point const &);
size_t size ();