diff --git a/nano/node/messages.cpp b/nano/node/messages.cpp index 4e8bb8e1e0..4b18d126c2 100644 --- a/nano/node/messages.cpp +++ b/nano/node/messages.cpp @@ -282,11 +282,11 @@ std::size_t nano::message_header::payload_length_bytes () const } case nano::message_type::confirm_ack: { - return nano::confirm_ack::size (count_get ()); + return nano::confirm_ack::size (*this); } case nano::message_type::confirm_req: { - return nano::confirm_req::size (block_type (), count_get ()); + return nano::confirm_req::size (*this); } case nano::message_type::node_id_handshake: { @@ -526,6 +526,7 @@ nano::confirm_req::confirm_req (nano::network_constants const & constants, std:: message (constants, nano::message_type::confirm_req), roots_hashes (roots_hashes_a) { + debug_assert (!roots_hashes.empty ()); debug_assert (roots_hashes.size () <= nano::vote::max_hashes); // not_a_block (1) block type for hashes + roots request @@ -534,15 +535,8 @@ nano::confirm_req::confirm_req (nano::network_constants const & constants, std:: } nano::confirm_req::confirm_req (nano::network_constants const & constants, nano::block_hash const & hash_a, nano::root const & root_a) : - message (constants, nano::message_type::confirm_req), - roots_hashes (std::vector> (1, std::make_pair (hash_a, root_a))) + confirm_req (constants, std::vector> (1, std::make_pair (hash_a, root_a))) { - debug_assert (!roots_hashes.empty ()); - debug_assert (roots_hashes.size () <= nano::vote::max_hashes); - - // not_a_block (1) block type for hashes + roots request - header.block_type_set (nano::block_type::not_a_block); - header.count_set (static_cast (roots_hashes.size ())); } void nano::confirm_req::visit (nano::message_visitor & visitor_a) const @@ -634,18 +628,19 @@ std::string nano::confirm_req::roots_string () const return result; } -std::size_t nano::confirm_req::size (nano::block_type type_a, std::size_t count) +std::size_t nano::confirm_req::size (const nano::message_header & header) { - std::size_t result (0); - if (type_a != nano::block_type::invalid && type_a != nano::block_type::not_a_block) + auto const type = header.block_type (); + if (type != nano::block_type::invalid && type != nano::block_type::not_a_block) { - result = nano::block::size (type_a); + return nano::block::size (type); } - else if (type_a == nano::block_type::not_a_block) + else if (type == nano::block_type::not_a_block) { - result = count * (sizeof (nano::uint256_union) + sizeof (nano::block_hash)); + auto const count = header.count_get (); + return count * (sizeof (hash_root_pair)); } - return result; + return 0; } std::string nano::confirm_req::to_string () const @@ -707,10 +702,10 @@ void nano::confirm_ack::visit (nano::message_visitor & visitor_a) const visitor_a.confirm_ack (*this); } -std::size_t nano::confirm_ack::size (std::size_t count) +std::size_t nano::confirm_ack::size (const nano::message_header & header) { - std::size_t result = sizeof (nano::account) + sizeof (nano::signature) + sizeof (uint64_t) + count * sizeof (nano::block_hash); - return result; + auto const count = header.count_get (); + return nano::vote::size (count); } std::string nano::confirm_ack::to_string () const diff --git a/nano/node/messages.hpp b/nano/node/messages.hpp index dfa344d59b..080fadb2bc 100644 --- a/nano/node/messages.hpp +++ b/nano/node/messages.hpp @@ -60,30 +60,38 @@ class message_visitor; class message_header final { public: + using extensions_bitset_t = std::bitset<16>; + message_header (nano::network_constants const &, nano::message_type); message_header (bool &, nano::stream &); + void serialize (nano::stream &) const; bool deserialize (nano::stream &); nano::block_type block_type () const; void block_type_set (nano::block_type); uint8_t count_get () const; void count_set (uint8_t); + + std::string to_string () const; + +public: // Payload nano::networks network; uint8_t version_max; uint8_t version_using; uint8_t version_min; - std::string to_string () const; + nano::message_type type; + extensions_bitset_t extensions; public: - nano::message_type type; - std::bitset<16> extensions; static std::size_t constexpr size = sizeof (nano::networks) + sizeof (version_max) + sizeof (version_using) + sizeof (version_min) + sizeof (type) + sizeof (/* extensions */ uint16_t); void flag_set (uint8_t, bool enable = true); + static uint8_t constexpr bulk_pull_count_present_flag = 0; static uint8_t constexpr bulk_pull_ascending_flag = 1; bool bulk_pull_is_count_present () const; bool bulk_pull_ascending () const; + static uint8_t constexpr frontier_req_only_confirmed = 1; bool frontier_req_is_only_confirmed_present () const; @@ -145,7 +153,7 @@ class publish final : public message class confirm_req final : public message { public: - confirm_req (bool &, nano::stream &, nano::message_header const &, nano::block_uniquer * = nullptr); + confirm_req (bool & error, nano::stream &, nano::message_header const &, nano::block_uniquer * = nullptr); confirm_req (nano::network_constants const & constants, std::shared_ptr const &); confirm_req (nano::network_constants const & constants, std::vector> const &); confirm_req (nano::network_constants const & constants, nano::block_hash const &, nano::root const &); @@ -156,26 +164,30 @@ class confirm_req final : public message void visit (nano::message_visitor &) const override; bool operator== (nano::confirm_req const &) const; std::string roots_string () const; - static std::size_t size (nano::block_type, std::size_t = 0); std::string to_string () const; + static std::size_t size (nano::message_header const &); + public: // Payload + using hash_root_pair = std::pair; + std::shared_ptr block; - std::vector> roots_hashes; + std::vector roots_hashes; }; class confirm_ack final : public message { public: - confirm_ack (bool &, nano::stream &, nano::message_header const &, nano::vote_uniquer * = nullptr); + confirm_ack (bool & error, nano::stream &, nano::message_header const &, nano::vote_uniquer * = nullptr); confirm_ack (nano::network_constants const & constants, std::shared_ptr const &); void serialize (nano::stream &) const override; void visit (nano::message_visitor &) const override; bool operator== (nano::confirm_ack const &) const; - static std::size_t size (std::size_t count); std::string to_string () const; + static std::size_t size (nano::message_header const &); + public: // Payload std::shared_ptr vote; }; diff --git a/nano/secure/vote.cpp b/nano/secure/vote.cpp index 0fa9d41d97..7ba49b98b8 100644 --- a/nano/secure/vote.cpp +++ b/nano/secure/vote.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -54,6 +55,12 @@ bool nano::vote::deserialize (nano::stream & stream_a) return error; } +std::size_t nano::vote::size (uint16_t count) +{ + debug_assert (count <= max_hashes); + return partial_size + count * sizeof (nano::block_hash); +} + std::string const nano::vote::hash_prefix = "vote "; nano::block_hash nano::vote::hash () const diff --git a/nano/secure/vote.hpp b/nano/secure/vote.hpp index cd8f2c8943..c3d0ba9741 100644 --- a/nano/secure/vote.hpp +++ b/nano/secure/vote.hpp @@ -33,6 +33,7 @@ class vote final * @returns true if there was an error */ bool deserialize (nano::stream &); + static std::size_t size (uint16_t count); nano::block_hash hash () const; nano::block_hash full_hash () const; @@ -62,11 +63,6 @@ class vote final /* Check if timestamp represents a final vote */ static bool is_final_timestamp (uint64_t timestamp); -private: - static std::string const hash_prefix; - - static uint64_t packed_timestamp (uint64_t timestamp, uint8_t duration); - public: // Payload // The hashes for which this vote directly covers std::vector hashes; @@ -78,5 +74,12 @@ class vote final private: // Payload // Vote timestamp uint64_t timestamp_m{ 0 }; + +private: + // Size of vote payload without hashes + static std::size_t constexpr partial_size = sizeof (account) + sizeof (signature) + sizeof (timestamp_m); + static std::string const hash_prefix; + + static uint64_t packed_timestamp (uint64_t timestamp, uint8_t duration); }; } \ No newline at end of file