Add size expressions to bootstrap types (#1580)

This commit is contained in:
cryptocode 2019-01-23 20:33:10 +01:00 committed by Roy Keene
commit 7a41f6daaf
4 changed files with 57 additions and 33 deletions

View file

@ -14,6 +14,8 @@ constexpr double bootstrap_minimum_termination_time_sec = 30.0;
constexpr unsigned bootstrap_max_new_connections = 10;
constexpr unsigned bulk_push_cost_limit = 200;
size_t constexpr nano::frontier_req_client::size_frontier;
nano::socket::socket (std::shared_ptr<nano::node> node_a) :
socket_m (node_a->io_ctx),
cutoff (std::numeric_limits<uint64_t>::max ()),
@ -239,11 +241,10 @@ nano::frontier_req_client::~frontier_req_client ()
void nano::frontier_req_client::receive_frontier ()
{
auto this_l (shared_from_this ());
size_t size_l (sizeof (nano::uint256_union) + sizeof (nano::uint256_union));
connection->socket->async_read (connection->receive_buffer, size_l, [this_l, size_l](boost::system::error_code const & ec, size_t size_a) {
connection->socket->async_read (connection->receive_buffer, nano::frontier_req_client::size_frontier, [this_l](boost::system::error_code const & ec, size_t size_a) {
// An issue with asio is that sometimes, instead of reporting a bad file descriptor during disconnect,
// we simply get a size of 0.
if (size_a == size_l)
if (size_a == nano::frontier_req_client::size_frontier)
{
this_l->received_frontier (ec, size_a);
}
@ -251,7 +252,7 @@ void nano::frontier_req_client::receive_frontier ()
{
if (this_l->connection->node->config.logging.network_message_logging ())
{
BOOST_LOG (this_l->connection->node->log) << boost::str (boost::format ("Invalid size: expected %1%, got %2%") % size_l % size_a);
BOOST_LOG (this_l->connection->node->log) << boost::str (boost::format ("Invalid size: expected %1%, got %2%") % nano::frontier_req_client::size_frontier % size_a);
}
}
});
@ -277,13 +278,13 @@ void nano::frontier_req_client::received_frontier (boost::system::error_code con
{
if (!ec)
{
assert (size_a == sizeof (nano::uint256_union) + sizeof (nano::uint256_union));
assert (size_a == nano::frontier_req_client::size_frontier);
nano::account account;
nano::bufferstream account_stream (connection->receive_buffer->data (), sizeof (nano::uint256_union));
nano::bufferstream account_stream (connection->receive_buffer->data (), sizeof (account));
auto error1 (nano::read (account_stream, account));
assert (!error1);
nano::block_hash latest;
nano::bufferstream latest_stream (connection->receive_buffer->data () + sizeof (nano::uint256_union), sizeof (nano::uint256_union));
nano::bufferstream latest_stream (connection->receive_buffer->data () + sizeof (account), sizeof (latest));
auto error2 (nano::read (latest_stream, latest));
assert (!error2);
if (count == 0)
@ -1999,20 +2000,10 @@ void nano::bootstrap_server::receive_header_action (boost::system::error_code co
{
case nano::message_type::bulk_pull:
{
uint32_t extended_size;
node->stats.inc (nano::stat::type::bootstrap, nano::stat::detail::bulk_pull, nano::stat::dir::in);
if (header.bulk_pull_is_count_present ())
{
extended_size = nano::bulk_pull::extended_parameters_size;
}
else
{
extended_size = 0;
}
auto this_l (shared_from_this ());
socket->async_read (receive_buffer, sizeof (nano::uint256_union) + sizeof (nano::uint256_union) + extended_size, [this_l, header](boost::system::error_code const & ec, size_t size_a) {
socket->async_read (receive_buffer, header.payload_length_bytes (), [this_l, header](boost::system::error_code const & ec, size_t size_a) {
this_l->receive_bulk_pull_action (ec, size_a, header);
});
break;
@ -2021,7 +2012,7 @@ void nano::bootstrap_server::receive_header_action (boost::system::error_code co
{
node->stats.inc (nano::stat::type::bootstrap, nano::stat::detail::bulk_pull_account, nano::stat::dir::in);
auto this_l (shared_from_this ());
socket->async_read (receive_buffer, sizeof (nano::uint256_union) + sizeof (nano::uint128_union) + sizeof (uint8_t), [this_l, header](boost::system::error_code const & ec, size_t size_a) {
socket->async_read (receive_buffer, header.payload_length_bytes (), [this_l, header](boost::system::error_code const & ec, size_t size_a) {
this_l->receive_bulk_pull_account_action (ec, size_a, header);
});
break;
@ -2030,7 +2021,7 @@ void nano::bootstrap_server::receive_header_action (boost::system::error_code co
{
node->stats.inc (nano::stat::type::bootstrap, nano::stat::detail::frontier_req, nano::stat::dir::in);
auto this_l (shared_from_this ());
socket->async_read (receive_buffer, sizeof (nano::uint256_union) + sizeof (uint32_t) + sizeof (uint32_t), [this_l, header](boost::system::error_code const & ec, size_t size_a) {
socket->async_read (receive_buffer, header.payload_length_bytes (), [this_l, header](boost::system::error_code const & ec, size_t size_a) {
this_l->receive_frontier_req_action (ec, size_a, header);
});
break;
@ -2085,7 +2076,7 @@ void nano::bootstrap_server::receive_bulk_pull_account_action (boost::system::er
if (!ec)
{
auto error (false);
assert (size_a == (sizeof (nano::uint256_union) + sizeof (nano::uint128_union) + sizeof (uint8_t)));
assert (size_a == header_a.payload_length_bytes ());
nano::bufferstream stream (receive_buffer->data (), size_a);
std::unique_ptr<nano::bulk_pull_account> request (new nano::bulk_pull_account (error, stream, header_a));
if (!error)
@ -2105,7 +2096,7 @@ void nano::bootstrap_server::receive_frontier_req_action (boost::system::error_c
if (!ec)
{
auto error (false);
nano::bufferstream stream (receive_buffer->data (), sizeof (nano::uint256_union) + sizeof (uint32_t) + sizeof (uint32_t));
nano::bufferstream stream (receive_buffer->data (), header_a.payload_length_bytes ());
std::unique_ptr<nano::frontier_req> request (new nano::frontier_req (error, stream, header_a));
if (!error)
{

View file

@ -155,6 +155,7 @@ public:
/** A very rough estimate of the cost of `bulk_push`ing missing blocks */
uint64_t bulk_push_cost;
std::deque<std::pair<nano::account, nano::block_hash>> accounts;
static size_t constexpr size_frontier = sizeof (nano::account) + sizeof (nano::block_hash);
};
class bulk_pull_client : public std::enable_shared_from_this<nano::bulk_pull_client>
{

View file

@ -88,6 +88,37 @@ bool nano::message_header::bulk_pull_is_count_present () const
return result;
}
size_t nano::message_header::payload_length_bytes () const
{
switch (type)
{
case nano::message_type::bulk_pull:
{
return nano::bulk_pull::size + (bulk_pull_is_count_present () ? nano::bulk_pull::extended_parameters_size : 0);
}
case nano::message_type::bulk_push:
{
// bulk_push doesn't have a payload
return 0;
}
case nano::message_type::frontier_req:
{
return nano::frontier_req::size;
}
case nano::message_type::bulk_pull_account:
{
return nano::bulk_pull_account::size;
}
// Add realtime network messages once they get framing support; currently the
// realtime messages all fit in a datagram from which they're deserialized.
default:
{
assert (false);
return 0;
}
}
}
// MTU - IP header - UDP header
const size_t nano::message_parser::max_safe_udp_message_size = 508;
@ -613,17 +644,17 @@ bool nano::bulk_pull::deserialize (nano::stream & stream_a)
{
if (is_count_present ())
{
std::array<uint8_t, extended_parameters_size> count_buffer;
static_assert (sizeof (count) < (count_buffer.size () - 1), "count must fit within buffer");
std::array<uint8_t, extended_parameters_size> extended_parameters_buffers;
static_assert (sizeof (count) < (extended_parameters_buffers.size () - 1), "count must fit within buffer");
result = read (stream_a, count_buffer);
if (count_buffer[0] != 0)
result = read (stream_a, extended_parameters_buffers);
if (extended_parameters_buffers[0] != 0)
{
result = true;
}
else
{
memcpy (&count, count_buffer.data () + 1, sizeof (count));
memcpy (&count, extended_parameters_buffers.data () + 1, sizeof (count));
boost::endian::little_to_native_inplace (count);
}
}

View file

@ -202,15 +202,13 @@ public:
uint8_t version_min;
nano::message_type type;
std::bitset<16> extensions;
//static size_t constexpr ipv4_only_position = 1; // Not in use, deprecated, was conflicting
//static size_t constexpr bootstrap_server_position = 2; // Not in use, deprecated
/*
* A better approach might be to return the size of the message
* payload based on the header
*/
static size_t constexpr bulk_pull_count_present_flag = 0;
bool bulk_pull_is_count_present () const;
/** Size of the payload in bytes. For some messages, the payload size is based on header flags. */
size_t payload_length_bytes () const;
static std::bitset<16> constexpr block_type_mask = std::bitset<16> (0x0f00);
bool valid_magic () const
{
@ -329,6 +327,7 @@ public:
nano::account start;
uint32_t age;
uint32_t count;
static size_t constexpr size = sizeof (start) + sizeof (age) + sizeof (count);
};
class bulk_pull : public message
{
@ -346,6 +345,7 @@ public:
void set_count_present (bool);
static size_t constexpr count_present_flag = nano::message_header::bulk_pull_count_present_flag;
static size_t constexpr extended_parameters_size = 8;
static size_t constexpr size = sizeof (start) + sizeof (end);
};
class bulk_pull_account : public message
{
@ -358,6 +358,7 @@ public:
nano::uint256_union account;
nano::uint128_union minimum_amount;
bulk_pull_account_flags flags;
static size_t constexpr size = sizeof (account) + sizeof (minimum_amount) + sizeof (bulk_pull_account_flags);
};
class bulk_push : public message
{