diff --git a/nano/core_test/message.cpp b/nano/core_test/message.cpp index 082a6009..039dbb1a 100644 --- a/nano/core_test/message.cpp +++ b/nano/core_test/message.cpp @@ -367,6 +367,47 @@ TEST (message, asc_pull_req_serialization_account_info) ASSERT_TRUE (nano::at_end (stream)); } +TEST (message, asc_pull_req_serialization_frontiers) +{ + nano::asc_pull_req original{ nano::dev::network_params.network }; + original.id = 7; + original.type = nano::asc_pull_type::frontiers; + + nano::asc_pull_req::frontiers_payload original_payload; + original_payload.start = nano::test::random_account (); + original_payload.count = 123; + + original.payload = original_payload; + original.update_header (); + + // Serialize + std::vector bytes; + { + nano::vectorstream stream{ bytes }; + original.serialize (stream); + } + nano::bufferstream stream{ bytes.data (), bytes.size () }; + + // Header + bool error = false; + nano::message_header header (error, stream); + ASSERT_FALSE (error); + ASSERT_EQ (nano::message_type::asc_pull_req, header.type); + + // Message + nano::asc_pull_req message (error, stream, header); + ASSERT_FALSE (error); + ASSERT_EQ (original.id, message.id); + ASSERT_EQ (original.type, message.type); + + nano::asc_pull_req::frontiers_payload message_payload; + ASSERT_NO_THROW (message_payload = std::get (message.payload)); + ASSERT_EQ (original_payload.start, message_payload.start); + ASSERT_EQ (original_payload.count, message_payload.count); + + ASSERT_TRUE (nano::at_end (stream)); +} + TEST (message, asc_pull_ack_serialization_blocks) { nano::asc_pull_ack original{ nano::dev::network_params.network }; @@ -466,6 +507,49 @@ TEST (message, asc_pull_ack_serialization_account_info) ASSERT_TRUE (nano::at_end (stream)); } +TEST (message, asc_pull_ack_serialization_frontiers) +{ + nano::asc_pull_ack original{ nano::dev::network_params.network }; + original.id = 11; + original.type = nano::asc_pull_type::frontiers; + + nano::asc_pull_ack::frontiers_payload original_payload; + for (int n = 0; n < nano::asc_pull_ack::frontiers_payload::max_frontiers; ++n) + { + original_payload.frontiers.push_back ({ nano::test::random_account (), nano::test::random_hash () }); + } + + original.payload = original_payload; + original.update_header (); + + // Serialize + std::vector bytes; + { + nano::vectorstream stream{ bytes }; + original.serialize (stream); + } + nano::bufferstream stream{ bytes.data (), bytes.size () }; + + // Header + bool error = false; + nano::message_header header (error, stream); + ASSERT_FALSE (error); + ASSERT_EQ (nano::message_type::asc_pull_ack, header.type); + + // Message + nano::asc_pull_ack message (error, stream, header); + ASSERT_FALSE (error); + ASSERT_EQ (original.id, message.id); + ASSERT_EQ (original.type, message.type); + + nano::asc_pull_ack::frontiers_payload message_payload; + ASSERT_NO_THROW (message_payload = std::get (message.payload)); + + ASSERT_EQ (original_payload.frontiers, message_payload.frontiers); + + ASSERT_TRUE (nano::at_end (stream)); +} + TEST (message, node_id_handshake_query_serialization) { nano::node_id_handshake::query_payload query{}; diff --git a/nano/node/messages.cpp b/nano/node/messages.cpp index 0837b756..435bda61 100644 --- a/nano/node/messages.cpp +++ b/nano/node/messages.cpp @@ -1974,6 +1974,8 @@ void nano::asc_pull_ack::account_info_payload::deserialize (nano::stream & strea void nano::asc_pull_ack::frontiers_payload::serialize (nano::stream & stream) const { + debug_assert (frontiers.size () <= max_frontiers); + for (auto const & [account, frontier] : frontiers) { nano::write (stream, account); @@ -1987,7 +1989,7 @@ void nano::asc_pull_ack::frontiers_payload::deserialize (nano::stream & stream) { nano::account account; nano::block_hash frontier; - while (frontiers.size () < max_frontiers) + while (true) { nano::read (stream, account); nano::read (stream, frontier); @@ -1995,6 +1997,14 @@ void nano::asc_pull_ack::frontiers_payload::deserialize (nano::stream & stream) { break; } - frontiers.emplace_back (account, frontier); + debug_assert (frontiers.size () < max_frontiers); + if (frontiers.size () < max_frontiers) + { + frontiers.emplace_back (account, frontier); + } + else + { + break; + } } } \ No newline at end of file