From 31b37e2c4692481ae20872f9dd5d87ff5a17c3db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Tue, 9 Jul 2024 17:01:48 +0200 Subject: [PATCH 1/6] Test telemetry data serialization --- nano/core_test/message.cpp | 64 ++++++++++++++++++++++++++++++++++-- nano/core_test/telemetry.cpp | 2 +- nano/node/messages.cpp | 14 ++------ nano/node/messages.hpp | 22 ++++++++----- 4 files changed, 78 insertions(+), 24 deletions(-) diff --git a/nano/core_test/message.cpp b/nano/core_test/message.cpp index 60d2338218..d506d83774 100644 --- a/nano/core_test/message.cpp +++ b/nano/core_test/message.cpp @@ -441,7 +441,7 @@ TEST (message, confirm_req_hash_batch_serialization_v2) /** * Test that a confirm_ack can encode an empty hash set */ -TEST (confirm_ack, empty_vote_hashes) +TEST (message, confirm_ack_empty_vote_hashes) { nano::keypair key; auto vote = std::make_shared (key.pub, key.prv, 0, 0, std::vector{} /* empty */); @@ -833,7 +833,7 @@ TEST (message, node_id_handshake_response_v2_serialization) ASSERT_TRUE (nano::at_end (stream)); } -TEST (handshake, signature) +TEST (message, handshake_signature) { nano::keypair node_id{}; nano::keypair node_id_2{}; @@ -853,7 +853,7 @@ TEST (handshake, signature) ASSERT_FALSE (response.validate (cookie)); } -TEST (handshake, signature_v2) +TEST (message, handshake_signature_v2) { nano::keypair node_id{}; nano::keypair node_id_2{}; @@ -895,3 +895,61 @@ TEST (handshake, signature_v2) ASSERT_FALSE (message.validate (cookie)); } } + +TEST (message, telemetry_data_serialization) +{ + nano::telemetry_data original; + original.node_id = nano::account{ 11111 }; + original.account_count = 22222; + original.block_count = 33333; + original.cemented_count = 44444; + original.bandwidth_cap = 55555; + original.account_count = 66666; + original.bandwidth_cap = 77777; + original.uptime = 88888; + original.peer_count = 99999; + original.protocol_version = 1; + original.genesis_block = nano::block_hash{ 22222 }; + original.major_version = 4; + original.minor_version = 3; + original.patch_version = 2; + original.pre_release_version = 1; + original.maker = 5; + original.timestamp = std::chrono::system_clock::time_point{ 123456789s }; + original.active_difficulty = 42; + + // Serialize + std::vector bytes; + { + nano::vectorstream stream{ bytes }; + original.serialize (stream); + } + nano::bufferstream stream{ bytes.data (), bytes.size () }; + + nano::telemetry_data telemetry; + ASSERT_NO_THROW (telemetry.deserialize (stream, bytes.size ())); + + // Compare + ASSERT_EQ (original.node_id, telemetry.node_id); + ASSERT_EQ (original.account_count, telemetry.account_count); + ASSERT_EQ (original.block_count, telemetry.block_count); + ASSERT_EQ (original.cemented_count, telemetry.cemented_count); + ASSERT_EQ (original.bandwidth_cap, telemetry.bandwidth_cap); + ASSERT_EQ (original.account_count, telemetry.account_count); + ASSERT_EQ (original.bandwidth_cap, telemetry.bandwidth_cap); + ASSERT_EQ (original.uptime, telemetry.uptime); + ASSERT_EQ (original.peer_count, telemetry.peer_count); + ASSERT_EQ (original.protocol_version, telemetry.protocol_version); + ASSERT_EQ (original.genesis_block, telemetry.genesis_block); + ASSERT_EQ (original.major_version, telemetry.major_version); + ASSERT_EQ (original.minor_version, telemetry.minor_version); + ASSERT_EQ (original.patch_version, telemetry.patch_version); + ASSERT_EQ (original.pre_release_version, telemetry.pre_release_version); + ASSERT_EQ (original.maker, telemetry.maker); + ASSERT_EQ (original.timestamp, telemetry.timestamp); + ASSERT_EQ (original.active_difficulty, telemetry.active_difficulty); + ASSERT_EQ (original, telemetry); + + ASSERT_EQ (nano::telemetry_data::size, bytes.size ()); + ASSERT_TRUE (nano::at_end (stream)); +} \ No newline at end of file diff --git a/nano/core_test/telemetry.cpp b/nano/core_test/telemetry.cpp index aafb6dda71..5620887a76 100644 --- a/nano/core_test/telemetry.cpp +++ b/nano/core_test/telemetry.cpp @@ -209,7 +209,7 @@ TEST (telemetry, max_possible_size) auto node_server = system.add_node (node_flags); nano::telemetry_data data; - data.unknown_data.resize (nano::message_header::telemetry_size_mask.to_ulong () - nano::telemetry_data::latest_size); + data.unknown_data.resize (nano::message_header::telemetry_size_mask.to_ulong () - nano::telemetry_data::size); nano::telemetry_ack message{ nano::dev::network_params.network, data }; nano::test::wait_peer_connections (system); diff --git a/nano/node/messages.cpp b/nano/node/messages.cpp index 0143a62b2e..d338501c44 100644 --- a/nano/node/messages.cpp +++ b/nano/node/messages.cpp @@ -1113,9 +1113,9 @@ void nano::telemetry_data::deserialize (nano::stream & stream_a, uint16_t payloa timestamp = std::chrono::system_clock::time_point (std::chrono::milliseconds (timestamp_l)); read (stream_a, active_difficulty); boost::endian::big_to_native_inplace (active_difficulty); - if (payload_length_a > latest_size) + if (payload_length_a > size) { - read (stream_a, unknown_data, payload_length_a - latest_size); + read (stream_a, unknown_data, payload_length_a - size); } } @@ -1230,16 +1230,6 @@ nano::error nano::telemetry_data::deserialize_json (nano::jsonconfig & json, boo return json.get_error (); } -bool nano::telemetry_data::operator== (nano::telemetry_data const & data_a) const -{ - return (signature == data_a.signature && node_id == data_a.node_id && block_count == data_a.block_count && cemented_count == data_a.cemented_count && unchecked_count == data_a.unchecked_count && account_count == data_a.account_count && bandwidth_cap == data_a.bandwidth_cap && uptime == data_a.uptime && peer_count == data_a.peer_count && protocol_version == data_a.protocol_version && genesis_block == data_a.genesis_block && major_version == data_a.major_version && minor_version == data_a.minor_version && patch_version == data_a.patch_version && pre_release_version == data_a.pre_release_version && maker == data_a.maker && timestamp == data_a.timestamp && active_difficulty == data_a.active_difficulty && unknown_data == data_a.unknown_data); -} - -bool nano::telemetry_data::operator!= (nano::telemetry_data const & data_a) const -{ - return !(*this == data_a); -} - void nano::telemetry_data::sign (nano::keypair const & node_id_a) { debug_assert (node_id == node_id_a.pub); diff --git a/nano/node/messages.hpp b/nano/node/messages.hpp index 7cba524971..b59deb8345 100644 --- a/nano/node/messages.hpp +++ b/nano/node/messages.hpp @@ -312,7 +312,7 @@ enum class telemetry_maker : uint8_t class telemetry_data { -public: +public: // Payload nano::signature signature{ 0 }; nano::account node_id{}; uint64_t block_count{ 0 }; @@ -333,18 +333,22 @@ class telemetry_data uint64_t active_difficulty{ 0 }; std::vector unknown_data; +public: void serialize (nano::stream &) const; - void deserialize (nano::stream &, uint16_t); - nano::error serialize_json (nano::jsonconfig &, bool) const; - nano::error deserialize_json (nano::jsonconfig &, bool); + void deserialize (nano::stream &, uint16_t payload_length); + + nano::error serialize_json (nano::jsonconfig &, bool ignore_identification_metrics) const; + nano::error deserialize_json (nano::jsonconfig &, bool ignore_identification_metrics); + void sign (nano::keypair const &); bool validate_signature () const; - bool operator== (nano::telemetry_data const &) const; - bool operator!= (nano::telemetry_data const &) const; + + bool operator== (nano::telemetry_data const &) const = default; + bool operator!= (nano::telemetry_data const &) const = default; // Size does not include unknown_data - static auto constexpr size = sizeof (signature) + sizeof (node_id) + sizeof (block_count) + sizeof (cemented_count) + sizeof (unchecked_count) + sizeof (account_count) + sizeof (bandwidth_cap) + sizeof (peer_count) + sizeof (protocol_version) + sizeof (uptime) + sizeof (genesis_block) + sizeof (major_version) + sizeof (minor_version) + sizeof (patch_version) + sizeof (pre_release_version) + sizeof (maker) + sizeof (uint64_t) + sizeof (active_difficulty); - static auto constexpr latest_size = size; // This needs to be updated for each new telemetry version + // This needs to be updated for each new telemetry version + static size_t constexpr size = sizeof (signature) + sizeof (node_id) + sizeof (block_count) + sizeof (cemented_count) + sizeof (unchecked_count) + sizeof (account_count) + sizeof (bandwidth_cap) + sizeof (peer_count) + sizeof (protocol_version) + sizeof (uptime) + sizeof (genesis_block) + sizeof (major_version) + sizeof (minor_version) + sizeof (patch_version) + sizeof (pre_release_version) + sizeof (maker) + sizeof (uint64_t) + sizeof (active_difficulty); private: void serialize_without_signature (nano::stream &) const; @@ -378,6 +382,8 @@ class telemetry_ack final : public message uint16_t size () const; bool is_empty_payload () const; static uint16_t size (nano::message_header const &); + +public: // Payload nano::telemetry_data data; public: // Logging From 49c8bd7b79ec929771e647d814d8f11fff2dade1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Mon, 15 Jul 2024 20:30:58 +0200 Subject: [PATCH 2/6] Avoid out of date code --- nano/rpc_test/rpc.cpp | 7 ++++- nano/test_common/telemetry.cpp | 48 +++++++++------------------------- nano/test_common/telemetry.hpp | 8 +----- 3 files changed, 20 insertions(+), 43 deletions(-) diff --git a/nano/rpc_test/rpc.cpp b/nano/rpc_test/rpc.cpp index 5ba2161d80..6d831e1522 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -6775,7 +6775,12 @@ TEST (rpc, telemetry_all) nano::telemetry_data telemetry_data; auto const should_ignore_identification_metrics = true; ASSERT_FALSE (telemetry_data.deserialize_json (config, should_ignore_identification_metrics)); - ASSERT_TRUE (nano::test::compare_telemetry_data (telemetry_data, node->local_telemetry ())); + auto local_telemetry = node->local_telemetry (); + // Ignore the identification metrics + local_telemetry.signature.clear (); + local_telemetry.node_id.clear (); + local_telemetry.timestamp = telemetry_data.timestamp = {}; + ASSERT_EQ (telemetry_data, local_telemetry); } request.put ("raw", "true"); diff --git a/nano/test_common/telemetry.cpp b/nano/test_common/telemetry.cpp index db2465e074..af07b3ecdd 100644 --- a/nano/test_common/telemetry.cpp +++ b/nano/test_common/telemetry.cpp @@ -7,56 +7,34 @@ namespace { -void compare_telemetry_data_impl (const nano::telemetry_data & data_a, const nano::telemetry_data & data_b, bool & result) -{ - ASSERT_EQ (data_a.block_count, data_b.block_count); - ASSERT_EQ (data_a.cemented_count, data_b.cemented_count); - ASSERT_EQ (data_a.bandwidth_cap, data_b.bandwidth_cap); - ASSERT_EQ (data_a.peer_count, data_b.peer_count); - ASSERT_EQ (data_a.protocol_version, data_b.protocol_version); - ASSERT_EQ (data_a.unchecked_count, data_b.unchecked_count); - ASSERT_EQ (data_a.account_count, data_b.account_count); - ASSERT_LE (data_a.uptime, data_b.uptime); - ASSERT_EQ (data_a.genesis_block, data_b.genesis_block); - ASSERT_EQ (data_a.major_version, nano::get_major_node_version ()); - ASSERT_EQ (data_a.minor_version, nano::get_minor_node_version ()); - ASSERT_EQ (data_a.patch_version, nano::get_patch_node_version ()); - ASSERT_EQ (data_a.pre_release_version, nano::get_pre_release_node_version ()); - ASSERT_EQ (data_a.maker, static_cast> (nano::telemetry_maker::nf_node)); - ASSERT_GT (data_a.timestamp, std::chrono::system_clock::now () - std::chrono::seconds (100)); - ASSERT_EQ (data_a.active_difficulty, data_b.active_difficulty); - ASSERT_EQ (data_a.unknown_data, std::vector{}); - result = true; -} -} - -bool nano::test::compare_telemetry_data (const nano::telemetry_data & data_a, const nano::telemetry_data & data_b) -{ - bool result = false; - compare_telemetry_data_impl (data_a, data_b, result); - return result; -} - -namespace -{ -void compare_telemetry_impl (const nano::telemetry_data & data, nano::node const & node, bool & result) +void compare_telemetry_impl (nano::telemetry_data data, nano::node const & node, bool & result) { ASSERT_FALSE (data.validate_signature ()); ASSERT_EQ (data.node_id, node.node_id.pub); + auto data_node = node.local_telemetry (); + + // Ignore timestamps and uptime + data.timestamp = data_node.timestamp = {}; + data.uptime = data_node.uptime = {}; + // Signature should be different because uptime/timestamp will have changed. nano::telemetry_data data_l = data; data_l.signature.clear (); data_l.sign (node.node_id); ASSERT_NE (data.signature, data_l.signature); - ASSERT_TRUE (nano::test::compare_telemetry_data (data, node.local_telemetry ())); + // Clear signatures for comparison + data.signature.clear (); + data_node.signature.clear (); + + ASSERT_EQ (data, data_node); result = true; } } -bool nano::test::compare_telemetry (const nano::telemetry_data & data, const nano::node & node) +bool nano::test::compare_telemetry (nano::telemetry_data data, const nano::node & node) { bool result = false; compare_telemetry_impl (data, node, result); diff --git a/nano/test_common/telemetry.hpp b/nano/test_common/telemetry.hpp index 3efdd06cf6..35892b3db6 100644 --- a/nano/test_common/telemetry.hpp +++ b/nano/test_common/telemetry.hpp @@ -8,15 +8,9 @@ class telemetry_data; namespace nano::test { -/** - * Compares telemetry data without signatures - * @return true if comparison OK - */ -bool compare_telemetry_data (nano::telemetry_data const &, nano::telemetry_data const &); - /** * Compares telemetry data and checks signature matches node_id * @return true if comparison OK */ -bool compare_telemetry (nano::telemetry_data const &, nano::node const &); +bool compare_telemetry (nano::telemetry_data, nano::node const &); } \ No newline at end of file From 07185c0cccd610297fb7b82f6d6e7a0ae8aa499a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Tue, 16 Jul 2024 11:55:24 +0200 Subject: [PATCH 3/6] Include database version --- nano/core_test/message.cpp | 8 +++ nano/node/messages.cpp | 127 +++++++++++++++++++++---------------- nano/node/messages.hpp | 16 ++++- nano/node/node.cpp | 51 +++++++++++++++ 4 files changed, 145 insertions(+), 57 deletions(-) diff --git a/nano/core_test/message.cpp b/nano/core_test/message.cpp index d506d83774..6a20cd7fcf 100644 --- a/nano/core_test/message.cpp +++ b/nano/core_test/message.cpp @@ -917,6 +917,10 @@ TEST (message, telemetry_data_serialization) original.maker = 5; original.timestamp = std::chrono::system_clock::time_point{ 123456789s }; original.active_difficulty = 42; + original.database_backend = 2; + original.database_version_major = 3; + original.database_version_minor = 2; + original.database_version_patch = 1; // Serialize std::vector bytes; @@ -948,6 +952,10 @@ TEST (message, telemetry_data_serialization) ASSERT_EQ (original.maker, telemetry.maker); ASSERT_EQ (original.timestamp, telemetry.timestamp); ASSERT_EQ (original.active_difficulty, telemetry.active_difficulty); + ASSERT_EQ (original.database_backend, telemetry.database_backend); + ASSERT_EQ (original.database_version_major, telemetry.database_version_major); + ASSERT_EQ (original.database_version_minor, telemetry.database_version_minor); + ASSERT_EQ (original.database_version_patch, telemetry.database_version_patch); ASSERT_EQ (original, telemetry); ASSERT_EQ (nano::telemetry_data::size, bytes.size ()); diff --git a/nano/node/messages.cpp b/nano/node/messages.cpp index d338501c44..d9c8ff641c 100644 --- a/nano/node/messages.cpp +++ b/nano/node/messages.cpp @@ -1081,74 +1081,83 @@ void nano::telemetry_ack::operator() (nano::object_stream & obs) const * telemetry_data */ -void nano::telemetry_data::deserialize (nano::stream & stream_a, uint16_t payload_length_a) +void nano::telemetry_data::deserialize (nano::stream & stream, uint16_t payload_length) { - read (stream_a, signature); - read (stream_a, node_id); - read (stream_a, block_count); + read (stream, signature); + read (stream, node_id); + read (stream, block_count); boost::endian::big_to_native_inplace (block_count); - read (stream_a, cemented_count); + read (stream, cemented_count); boost::endian::big_to_native_inplace (cemented_count); - read (stream_a, unchecked_count); + read (stream, unchecked_count); boost::endian::big_to_native_inplace (unchecked_count); - read (stream_a, account_count); + read (stream, account_count); boost::endian::big_to_native_inplace (account_count); - read (stream_a, bandwidth_cap); + read (stream, bandwidth_cap); boost::endian::big_to_native_inplace (bandwidth_cap); - read (stream_a, peer_count); + read (stream, peer_count); boost::endian::big_to_native_inplace (peer_count); - read (stream_a, protocol_version); - read (stream_a, uptime); + read (stream, protocol_version); + read (stream, uptime); boost::endian::big_to_native_inplace (uptime); - read (stream_a, genesis_block.bytes); - read (stream_a, major_version); - read (stream_a, minor_version); - read (stream_a, patch_version); - read (stream_a, pre_release_version); - read (stream_a, maker); + read (stream, genesis_block.bytes); + read (stream, major_version); + read (stream, minor_version); + read (stream, patch_version); + read (stream, pre_release_version); + read (stream, maker); uint64_t timestamp_l; - read (stream_a, timestamp_l); + read (stream, timestamp_l); boost::endian::big_to_native_inplace (timestamp_l); timestamp = std::chrono::system_clock::time_point (std::chrono::milliseconds (timestamp_l)); - read (stream_a, active_difficulty); + read (stream, active_difficulty); boost::endian::big_to_native_inplace (active_difficulty); - if (payload_length_a > size) + read (stream, database_backend); + read (stream, database_version_major); + read (stream, database_version_minor); + read (stream, database_version_patch); + + if (payload_length > size) { - read (stream_a, unknown_data, payload_length_a - size); + read (stream, unknown_data, payload_length - size); } } -void nano::telemetry_data::serialize_without_signature (nano::stream & stream_a) const +void nano::telemetry_data::serialize_without_signature (nano::stream & stream) const { // All values should be serialized in big endian - write (stream_a, node_id); - write (stream_a, boost::endian::native_to_big (block_count)); - write (stream_a, boost::endian::native_to_big (cemented_count)); - write (stream_a, boost::endian::native_to_big (unchecked_count)); - write (stream_a, boost::endian::native_to_big (account_count)); - write (stream_a, boost::endian::native_to_big (bandwidth_cap)); - write (stream_a, boost::endian::native_to_big (peer_count)); - write (stream_a, protocol_version); - write (stream_a, boost::endian::native_to_big (uptime)); - write (stream_a, genesis_block.bytes); - write (stream_a, major_version); - write (stream_a, minor_version); - write (stream_a, patch_version); - write (stream_a, pre_release_version); - write (stream_a, maker); - write (stream_a, boost::endian::native_to_big (std::chrono::duration_cast (timestamp.time_since_epoch ()).count ())); - write (stream_a, boost::endian::native_to_big (active_difficulty)); - write (stream_a, unknown_data); -} - -void nano::telemetry_data::serialize (nano::stream & stream_a) const -{ - write (stream_a, signature); - serialize_without_signature (stream_a); -} - -nano::error nano::telemetry_data::serialize_json (nano::jsonconfig & json, bool ignore_identification_metrics_a) const + write (stream, node_id); + write (stream, boost::endian::native_to_big (block_count)); + write (stream, boost::endian::native_to_big (cemented_count)); + write (stream, boost::endian::native_to_big (unchecked_count)); + write (stream, boost::endian::native_to_big (account_count)); + write (stream, boost::endian::native_to_big (bandwidth_cap)); + write (stream, boost::endian::native_to_big (peer_count)); + write (stream, protocol_version); + write (stream, boost::endian::native_to_big (uptime)); + write (stream, genesis_block.bytes); + write (stream, major_version); + write (stream, minor_version); + write (stream, patch_version); + write (stream, pre_release_version); + write (stream, maker); + write (stream, boost::endian::native_to_big (std::chrono::duration_cast (timestamp.time_since_epoch ()).count ())); + write (stream, boost::endian::native_to_big (active_difficulty)); + write (stream, database_backend); + write (stream, database_version_major); + write (stream, database_version_minor); + write (stream, database_version_patch); + write (stream, unknown_data); +} + +void nano::telemetry_data::serialize (nano::stream & stream) const +{ + write (stream, signature); + serialize_without_signature (stream); +} + +nano::error nano::telemetry_data::serialize_json (nano::jsonconfig & json, bool ignore_identification_metrics) const { json.put ("block_count", block_count); json.put ("cemented_count", cemented_count); @@ -1163,11 +1172,15 @@ nano::error nano::telemetry_data::serialize_json (nano::jsonconfig & json, bool json.put ("minor_version", minor_version); json.put ("patch_version", patch_version); json.put ("pre_release_version", pre_release_version); - json.put ("maker", maker); + json.put ("maker", maker); // TODO: This should be using a string representation json.put ("timestamp", std::chrono::duration_cast (timestamp.time_since_epoch ()).count ()); json.put ("active_difficulty", nano::to_string_hex (active_difficulty)); + json.put ("database_backend", database_backend); // TODO: This should be using a string representation + json.put ("database_version_major", database_version_major); + json.put ("database_version_minor", database_version_minor); + json.put ("database_version_patch", database_version_patch); // Keep these last for UI purposes - if (!ignore_identification_metrics_a) + if (!ignore_identification_metrics) { json.put ("node_id", node_id.to_node_id ()); json.put ("signature", signature.to_string ()); @@ -1175,9 +1188,9 @@ nano::error nano::telemetry_data::serialize_json (nano::jsonconfig & json, bool return json.get_error (); } -nano::error nano::telemetry_data::deserialize_json (nano::jsonconfig & json, bool ignore_identification_metrics_a) +nano::error nano::telemetry_data::deserialize_json (nano::jsonconfig & json, bool ignore_identification_metrics) { - if (!ignore_identification_metrics_a) + if (!ignore_identification_metrics) { std::string signature_l; json.get ("signature", signature_l); @@ -1221,12 +1234,16 @@ nano::error nano::telemetry_data::deserialize_json (nano::jsonconfig & json, boo json.get ("minor_version", minor_version); json.get ("patch_version", patch_version); json.get ("pre_release_version", pre_release_version); - json.get ("maker", maker); + json.get ("maker", maker); // TODO: This should be using a string representation auto timestamp_l = json.get ("timestamp"); timestamp = std::chrono::system_clock::time_point (std::chrono::milliseconds (timestamp_l)); auto current_active_difficulty_text = json.get ("active_difficulty"); auto ec = nano::from_string_hex (current_active_difficulty_text, active_difficulty); debug_assert (!ec); + json.get ("database_backend", database_backend); // TODO: This should be using a string representation + json.get ("database_version_major", database_version_major); + json.get ("database_version_minor", database_version_minor); + json.get ("database_version_patch", database_version_patch); return json.get_error (); } @@ -1238,7 +1255,6 @@ void nano::telemetry_data::sign (nano::keypair const & node_id_a) nano::vectorstream stream (bytes); serialize_without_signature (stream); } - signature = nano::sign_message (node_id_a.prv, node_id_a.pub, bytes.data (), bytes.size ()); } @@ -1249,7 +1265,6 @@ bool nano::telemetry_data::validate_signature () const nano::vectorstream stream (bytes); serialize_without_signature (stream); } - return nano::validate_message (node_id, bytes.data (), bytes.size (), signature); } diff --git a/nano/node/messages.hpp b/nano/node/messages.hpp index b59deb8345..b598b9efb2 100644 --- a/nano/node/messages.hpp +++ b/nano/node/messages.hpp @@ -310,6 +310,13 @@ enum class telemetry_maker : uint8_t nf_pruned_node = 1 }; +enum class telemetry_backend : uint8_t +{ + unknown = 0, + lmdb = 1, + rocksdb = 2, +}; + class telemetry_data { public: // Payload @@ -331,6 +338,13 @@ class telemetry_data uint8_t maker{ static_cast> (telemetry_maker::nf_node) }; // Where this telemetry information originated std::chrono::system_clock::time_point timestamp; uint64_t active_difficulty{ 0 }; + uint8_t database_backend{ 0 }; + uint8_t database_version_major{ 0 }; + uint8_t database_version_minor{ 0 }; + uint8_t database_version_patch{ 0 }; + + // Remaining data that might be present in future telemetry versions, kept here so we can re-serialize it + // TODO: Is supporting re-serialization necessary? std::vector unknown_data; public: @@ -348,7 +362,7 @@ class telemetry_data // Size does not include unknown_data // This needs to be updated for each new telemetry version - static size_t constexpr size = sizeof (signature) + sizeof (node_id) + sizeof (block_count) + sizeof (cemented_count) + sizeof (unchecked_count) + sizeof (account_count) + sizeof (bandwidth_cap) + sizeof (peer_count) + sizeof (protocol_version) + sizeof (uptime) + sizeof (genesis_block) + sizeof (major_version) + sizeof (minor_version) + sizeof (patch_version) + sizeof (pre_release_version) + sizeof (maker) + sizeof (uint64_t) + sizeof (active_difficulty); + static size_t constexpr size = sizeof (signature) + sizeof (node_id) + sizeof (block_count) + sizeof (cemented_count) + sizeof (unchecked_count) + sizeof (account_count) + sizeof (bandwidth_cap) + sizeof (peer_count) + sizeof (protocol_version) + sizeof (uptime) + sizeof (genesis_block) + sizeof (major_version) + sizeof (minor_version) + sizeof (patch_version) + sizeof (pre_release_version) + sizeof (maker) + sizeof (uint64_t) + sizeof (active_difficulty) + sizeof (database_backend) + sizeof (database_version_major) + sizeof (database_version_minor) + sizeof (database_version_patch); private: void serialize_without_signature (nano::stream &) const; diff --git a/nano/node/node.cpp b/nano/node/node.cpp index f296ae5cca..e972e1b26f 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -1335,6 +1335,52 @@ nano::account nano::node::get_node_id () const nano::telemetry_data nano::node::local_telemetry () const { + struct database_details_t + { + nano::telemetry_backend backend{ telemetry_backend::unknown }; + uint8_t version_major{ 0 }; + uint8_t version_minor{ 0 }; + uint8_t version_patch{ 0 }; + }; + + auto parse_backend_type = [] (std::string backend) -> telemetry_backend { + // Compare with lowercase + std::transform (backend.begin (), backend.end (), backend.begin (), ::tolower); + + if (backend == "lmdb") + { + return telemetry_backend::lmdb; + } + if (backend == "rocksdb") + { + return telemetry_backend::rocksdb; + } + debug_assert (false, "invalid database backend string"); + return telemetry_backend::unknown; + }; + + auto parse_backend_vendor = [&] (std::string vendor) -> database_details_t { + // Expected format: "DB_TYPE X.Y.Z" + auto type_version_split = nano::util::split (vendor, " "); + if (type_version_split.size () == 2) + { + auto version_split = nano::util::split (type_version_split[1], "."); + if (version_split.size () == 3) + { + return { + .backend = parse_backend_type (type_version_split[0]), + .version_major = static_cast (std::stoul (version_split[0])), + .version_minor = static_cast (std::stoul (version_split[1])), + .version_patch = static_cast (std::stoul (version_split[2])), + }; + } + } + debug_assert (false, "invalid database vendor string"); + return {}; + }; + + auto backend_details = parse_backend_vendor (store.vendor_get ()); + nano::telemetry_data telemetry_data; telemetry_data.node_id = node_id.pub; telemetry_data.block_count = ledger.block_count (); @@ -1353,6 +1399,11 @@ nano::telemetry_data nano::node::local_telemetry () const telemetry_data.maker = static_cast> (ledger.pruning ? telemetry_maker::nf_pruned_node : telemetry_maker::nf_node); telemetry_data.timestamp = std::chrono::system_clock::now (); telemetry_data.active_difficulty = default_difficulty (nano::work_version::work_1); + telemetry_data.database_backend = static_cast> (backend_details.backend); + telemetry_data.database_version_major = backend_details.version_major; + telemetry_data.database_version_minor = backend_details.version_minor; + telemetry_data.database_version_patch = backend_details.version_patch; + // Make sure this is the final operation! telemetry_data.sign (node_id); return telemetry_data; From 595fcade21e52e7abf0470c7ae8166c14ddb6b7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Tue, 16 Jul 2024 14:43:34 +0200 Subject: [PATCH 4/6] Use enum as backend type # Conflicts: # nano/core_test/message.cpp # nano/core_test/telemetry.cpp # nano/node/telemetry.cpp --- nano/core_test/message.cpp | 2 +- nano/node/messages.cpp | 79 ++++++++++++++++++++++++++++++++++++-- nano/node/messages.hpp | 8 +++- nano/node/node.cpp | 4 +- nano/node/telemetry.cpp | 4 +- 5 files changed, 88 insertions(+), 9 deletions(-) diff --git a/nano/core_test/message.cpp b/nano/core_test/message.cpp index 6a20cd7fcf..9d77794525 100644 --- a/nano/core_test/message.cpp +++ b/nano/core_test/message.cpp @@ -917,7 +917,7 @@ TEST (message, telemetry_data_serialization) original.maker = 5; original.timestamp = std::chrono::system_clock::time_point{ 123456789s }; original.active_difficulty = 42; - original.database_backend = 2; + original.database_backend = nano::telemetry_backend::rocksdb; original.database_version_major = 3; original.database_version_minor = 2; original.database_version_patch = 1; diff --git a/nano/node/messages.cpp b/nano/node/messages.cpp index d9c8ff641c..4be7a7a2b5 100644 --- a/nano/node/messages.cpp +++ b/nano/node/messages.cpp @@ -1111,9 +1111,14 @@ void nano::telemetry_data::deserialize (nano::stream & stream, uint16_t payload_ read (stream, timestamp_l); boost::endian::big_to_native_inplace (timestamp_l); timestamp = std::chrono::system_clock::time_point (std::chrono::milliseconds (timestamp_l)); + read (stream, active_difficulty); boost::endian::big_to_native_inplace (active_difficulty); - read (stream, database_backend); + + uint8_t database_backend_l; + read (stream, database_backend_l); + database_backend = static_cast (database_backend_l); + read (stream, database_version_major); read (stream, database_version_minor); read (stream, database_version_patch); @@ -1144,7 +1149,7 @@ void nano::telemetry_data::serialize_without_signature (nano::stream & stream) c write (stream, maker); write (stream, boost::endian::native_to_big (std::chrono::duration_cast (timestamp.time_since_epoch ()).count ())); write (stream, boost::endian::native_to_big (active_difficulty)); - write (stream, database_backend); + write (stream, static_cast> (database_backend)); write (stream, database_version_major); write (stream, database_version_minor); write (stream, database_version_patch); @@ -1175,7 +1180,7 @@ nano::error nano::telemetry_data::serialize_json (nano::jsonconfig & json, bool json.put ("maker", maker); // TODO: This should be using a string representation json.put ("timestamp", std::chrono::duration_cast (timestamp.time_since_epoch ()).count ()); json.put ("active_difficulty", nano::to_string_hex (active_difficulty)); - json.put ("database_backend", database_backend); // TODO: This should be using a string representation + json.put ("database_backend", to_string (database_backend)); json.put ("database_version_major", database_version_major); json.put ("database_version_minor", database_version_minor); json.put ("database_version_patch", database_version_patch); @@ -1221,6 +1226,7 @@ nano::error nano::telemetry_data::deserialize_json (nano::jsonconfig & json, boo json.get ("peer_count", peer_count); json.get ("protocol_version", protocol_version); json.get ("uptime", uptime); + std::string genesis_block_l; json.get ("genesis_block", genesis_block_l); if (!json.get_error ()) @@ -1230,17 +1236,24 @@ nano::error nano::telemetry_data::deserialize_json (nano::jsonconfig & json, boo json.get_error ().set ("Could not deserialize genesis block"); } } + json.get ("major_version", major_version); json.get ("minor_version", minor_version); json.get ("patch_version", patch_version); json.get ("pre_release_version", pre_release_version); json.get ("maker", maker); // TODO: This should be using a string representation + auto timestamp_l = json.get ("timestamp"); timestamp = std::chrono::system_clock::time_point (std::chrono::milliseconds (timestamp_l)); + auto current_active_difficulty_text = json.get ("active_difficulty"); auto ec = nano::from_string_hex (current_active_difficulty_text, active_difficulty); debug_assert (!ec); - json.get ("database_backend", database_backend); // TODO: This should be using a string representation + + std::string database_backend_text; + json.get ("database_backend", database_backend_text); + database_backend = nano::to_telemetry_backend (database_backend_text); + json.get ("database_version_major", database_version_major); json.get ("database_version_minor", database_version_minor); json.get ("database_version_patch", database_version_patch); @@ -1273,6 +1286,64 @@ void nano::telemetry_data::operator() (nano::object_stream & obs) const // TODO: Telemetry data } +std::string nano::to_string (nano::telemetry_maker maker) +{ + switch (maker) + { + case nano::telemetry_maker::nf_node: + return "nf"; + case nano::telemetry_maker::nf_pruned_node: + return "nf-pruned"; + } + return "unknown (" + std::to_string (static_cast> (maker)) + ")"; +} + +nano::telemetry_maker nano::to_telemetry_maker (std::string str) +{ + // Convert to lowercase + std::transform (str.begin (), str.end (), str.begin (), ::tolower); + + if (str == "nf") + { + return nano::telemetry_maker::nf_node; + } + if (str == "nf-pruned") + { + return nano::telemetry_maker::nf_pruned_node; + } + return {}; // TODO: Enumeration should have a default "unknown" value, at this point it's probably too late to add it +} + +std::string nano::to_string (nano::telemetry_backend backend) +{ + switch (backend) + { + case nano::telemetry_backend::unknown: + return "Unknown"; + case nano::telemetry_backend::lmdb: + return "LMDB"; + case nano::telemetry_backend::rocksdb: + return "RocksDB"; + } + return "Unknown (" + std::to_string (static_cast> (backend)) + ")"; +} + +nano::telemetry_backend nano::to_telemetry_backend (std::string str) +{ + // Convert to lowercase + std::transform (str.begin (), str.end (), str.begin (), ::tolower); + + if (str == "lmdb") + { + return nano::telemetry_backend::lmdb; + } + if (str == "rocksdb") + { + return nano::telemetry_backend::rocksdb; + } + return nano::telemetry_backend::unknown; +} + /* * node_id_handshake */ diff --git a/nano/node/messages.hpp b/nano/node/messages.hpp index b598b9efb2..3a34b4886a 100644 --- a/nano/node/messages.hpp +++ b/nano/node/messages.hpp @@ -317,6 +317,12 @@ enum class telemetry_backend : uint8_t rocksdb = 2, }; +std::string to_string (telemetry_maker); +telemetry_maker to_telemetry_maker (std::string); + +std::string to_string (telemetry_backend); +telemetry_backend to_telemetry_backend (std::string); + class telemetry_data { public: // Payload @@ -338,7 +344,7 @@ class telemetry_data uint8_t maker{ static_cast> (telemetry_maker::nf_node) }; // Where this telemetry information originated std::chrono::system_clock::time_point timestamp; uint64_t active_difficulty{ 0 }; - uint8_t database_backend{ 0 }; + telemetry_backend database_backend{ telemetry_backend::unknown }; uint8_t database_version_major{ 0 }; uint8_t database_version_minor{ 0 }; uint8_t database_version_patch{ 0 }; diff --git a/nano/node/node.cpp b/nano/node/node.cpp index e972e1b26f..76d000de97 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -1344,7 +1344,7 @@ nano::telemetry_data nano::node::local_telemetry () const }; auto parse_backend_type = [] (std::string backend) -> telemetry_backend { - // Compare with lowercase + // Convert to lowercase std::transform (backend.begin (), backend.end (), backend.begin (), ::tolower); if (backend == "lmdb") @@ -1399,7 +1399,7 @@ nano::telemetry_data nano::node::local_telemetry () const telemetry_data.maker = static_cast> (ledger.pruning ? telemetry_maker::nf_pruned_node : telemetry_maker::nf_node); telemetry_data.timestamp = std::chrono::system_clock::now (); telemetry_data.active_difficulty = default_difficulty (nano::work_version::work_1); - telemetry_data.database_backend = static_cast> (backend_details.backend); + telemetry_data.database_backend = backend_details.backend; telemetry_data.database_version_major = backend_details.version_major; telemetry_data.database_version_minor = backend_details.version_minor; telemetry_data.database_version_patch = backend_details.version_patch; diff --git a/nano/node/telemetry.cpp b/nano/node/telemetry.cpp index 9016b73d1e..aa27ac4835 100644 --- a/nano/node/telemetry.cpp +++ b/nano/node/telemetry.cpp @@ -16,6 +16,8 @@ #include #include +#include + using namespace std::chrono_literals; nano::telemetry::telemetry (const config & config_a, nano::node & node_a, nano::network & network_a, nano::node_observers & observers_a, nano::network_params & network_params_a, nano::stats & stats_a) : @@ -296,4 +298,4 @@ std::unique_ptr nano::telemetry::collect_contain auto composite = std::make_unique (name); composite->add_component (std::make_unique (container_info{ "telemetries", telemetries.size (), sizeof (decltype (telemetries)::value_type) })); return composite; -} \ No newline at end of file +} From 009a4bae2a77979feac4e5b6e5323e81b67fe9a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Wed, 17 Jul 2024 17:20:22 +0200 Subject: [PATCH 5/6] Use enum as maker type --- nano/core_test/message.cpp | 2 +- nano/core_test/telemetry.cpp | 5 ++--- nano/node/messages.cpp | 18 ++++++++++++------ nano/node/messages.hpp | 5 ++++- nano/node/node.cpp | 2 +- nano/slow_test/node.cpp | 2 +- 6 files changed, 21 insertions(+), 13 deletions(-) diff --git a/nano/core_test/message.cpp b/nano/core_test/message.cpp index 9d77794525..e5c08adc20 100644 --- a/nano/core_test/message.cpp +++ b/nano/core_test/message.cpp @@ -914,7 +914,7 @@ TEST (message, telemetry_data_serialization) original.minor_version = 3; original.patch_version = 2; original.pre_release_version = 1; - original.maker = 5; + original.maker = nano::telemetry_maker::nf_pruned_node; original.timestamp = std::chrono::system_clock::time_point{ 123456789s }; original.active_difficulty = 42; original.database_backend = nano::telemetry_backend::rocksdb; diff --git a/nano/core_test/telemetry.cpp b/nano/core_test/telemetry.cpp index 5620887a76..142db6db99 100644 --- a/nano/core_test/telemetry.cpp +++ b/nano/core_test/telemetry.cpp @@ -19,13 +19,13 @@ TEST (telemetry, signatures) data.minor_version = 1; data.patch_version = 5; data.pre_release_version = 2; - data.maker = 1; + data.maker = nano::telemetry_maker::nf_pruned_node; data.timestamp = std::chrono::system_clock::time_point (100ms); data.sign (node_id); ASSERT_FALSE (data.validate_signature ()); auto signature = data.signature; // Check that the signature is different if changing a piece of data - data.maker = 2; + data.maker = nano::telemetry_maker::nf_node; data.sign (node_id); ASSERT_NE (data.signature, signature); } @@ -39,7 +39,6 @@ TEST (telemetry, unknown_data) data.minor_version = 1; data.patch_version = 5; data.pre_release_version = 2; - data.maker = 1; data.timestamp = std::chrono::system_clock::time_point (100ms); data.unknown_data.push_back (1); data.sign (node_id); diff --git a/nano/node/messages.cpp b/nano/node/messages.cpp index 4be7a7a2b5..042c509fae 100644 --- a/nano/node/messages.cpp +++ b/nano/node/messages.cpp @@ -1105,7 +1105,10 @@ void nano::telemetry_data::deserialize (nano::stream & stream, uint16_t payload_ read (stream, minor_version); read (stream, patch_version); read (stream, pre_release_version); - read (stream, maker); + + uint8_t maker_l; + read (stream, maker_l); + maker = static_cast (maker_l); uint64_t timestamp_l; read (stream, timestamp_l); @@ -1146,7 +1149,7 @@ void nano::telemetry_data::serialize_without_signature (nano::stream & stream) c write (stream, minor_version); write (stream, patch_version); write (stream, pre_release_version); - write (stream, maker); + write (stream, static_cast> (maker)); write (stream, boost::endian::native_to_big (std::chrono::duration_cast (timestamp.time_since_epoch ()).count ())); write (stream, boost::endian::native_to_big (active_difficulty)); write (stream, static_cast> (database_backend)); @@ -1177,7 +1180,7 @@ nano::error nano::telemetry_data::serialize_json (nano::jsonconfig & json, bool json.put ("minor_version", minor_version); json.put ("patch_version", patch_version); json.put ("pre_release_version", pre_release_version); - json.put ("maker", maker); // TODO: This should be using a string representation + json.put ("maker", to_string (maker)); json.put ("timestamp", std::chrono::duration_cast (timestamp.time_since_epoch ()).count ()); json.put ("active_difficulty", nano::to_string_hex (active_difficulty)); json.put ("database_backend", to_string (database_backend)); @@ -1236,12 +1239,15 @@ nano::error nano::telemetry_data::deserialize_json (nano::jsonconfig & json, boo json.get_error ().set ("Could not deserialize genesis block"); } } - + json.get ("major_version", major_version); json.get ("minor_version", minor_version); json.get ("patch_version", patch_version); json.get ("pre_release_version", pre_release_version); - json.get ("maker", maker); // TODO: This should be using a string representation + + std::string maker_text; + json.get ("maker", maker_text); + maker = to_telemetry_maker (maker_text); auto timestamp_l = json.get ("timestamp"); timestamp = std::chrono::system_clock::time_point (std::chrono::milliseconds (timestamp_l)); @@ -1252,7 +1258,7 @@ nano::error nano::telemetry_data::deserialize_json (nano::jsonconfig & json, boo std::string database_backend_text; json.get ("database_backend", database_backend_text); - database_backend = nano::to_telemetry_backend (database_backend_text); + database_backend = to_telemetry_backend (database_backend_text); json.get ("database_version_major", database_version_major); json.get ("database_version_minor", database_version_minor); diff --git a/nano/node/messages.hpp b/nano/node/messages.hpp index 3a34b4886a..cf49dbeb47 100644 --- a/nano/node/messages.hpp +++ b/nano/node/messages.hpp @@ -304,12 +304,15 @@ class frontier_req final : public message void operator() (nano::object_stream &) const override; }; +// Indicates type of node enum class telemetry_maker : uint8_t { + // TODO: Default 0 value should be "unknown" nf_node = 0, nf_pruned_node = 1 }; +// Indicates type of database backend enum class telemetry_backend : uint8_t { unknown = 0, @@ -341,7 +344,7 @@ class telemetry_data uint8_t minor_version{ 0 }; uint8_t patch_version{ 0 }; uint8_t pre_release_version{ 0 }; - uint8_t maker{ static_cast> (telemetry_maker::nf_node) }; // Where this telemetry information originated + telemetry_maker maker{ telemetry_maker::nf_node }; std::chrono::system_clock::time_point timestamp; uint64_t active_difficulty{ 0 }; telemetry_backend database_backend{ telemetry_backend::unknown }; diff --git a/nano/node/node.cpp b/nano/node/node.cpp index 76d000de97..9ea650a828 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -1396,7 +1396,7 @@ nano::telemetry_data nano::node::local_telemetry () const telemetry_data.minor_version = nano::get_minor_node_version (); telemetry_data.patch_version = nano::get_patch_node_version (); telemetry_data.pre_release_version = nano::get_pre_release_node_version (); - telemetry_data.maker = static_cast> (ledger.pruning ? telemetry_maker::nf_pruned_node : telemetry_maker::nf_node); + telemetry_data.maker = ledger.pruning ? telemetry_maker::nf_pruned_node : telemetry_maker::nf_node; telemetry_data.timestamp = std::chrono::system_clock::now (); telemetry_data.active_difficulty = default_difficulty (nano::work_version::work_1); telemetry_data.database_backend = backend_details.backend; diff --git a/nano/slow_test/node.cpp b/nano/slow_test/node.cpp index 1ea6065a40..8bf02f626a 100644 --- a/nano/slow_test/node.cpp +++ b/nano/slow_test/node.cpp @@ -1632,7 +1632,7 @@ TEST (telemetry, many_nodes) ASSERT_EQ (data.minor_version, nano::get_minor_node_version ()); ASSERT_EQ (data.patch_version, nano::get_patch_node_version ()); ASSERT_EQ (data.pre_release_version, nano::get_pre_release_node_version ()); - ASSERT_EQ (data.maker, 0); + ASSERT_EQ (data.maker, nano::telemetry_maker::nf_node); ASSERT_LT (data.uptime, 100); ASSERT_EQ (data.genesis_block, nano::dev::genesis->hash ()); ASSERT_LE (data.timestamp, std::chrono::system_clock::now ()); From 5791b137de294c151ede010cb17da7010c253f2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Tue, 6 Aug 2024 11:20:07 +0200 Subject: [PATCH 6/6] Backwards compatibility --- nano/node/messages.cpp | 20 +++++++++++++++++--- nano/node/messages.hpp | 11 +++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/nano/node/messages.cpp b/nano/node/messages.cpp index 042c509fae..5ac44fca38 100644 --- a/nano/node/messages.cpp +++ b/nano/node/messages.cpp @@ -1036,14 +1036,13 @@ bool nano::telemetry_ack::deserialize (nano::stream & stream_a) { if (!is_empty_payload ()) { - data.deserialize (stream_a, nano::narrow_cast (header.extensions.to_ulong ())); + data.deserialize (stream_a, size ()); } } catch (std::runtime_error const &) { - error = true; + // Ignore deserialization errors for backwards compatibility } - return error; } @@ -1083,7 +1082,10 @@ void nano::telemetry_ack::operator() (nano::object_stream & obs) const void nano::telemetry_data::deserialize (nano::stream & stream, uint16_t payload_length) { + version = version_t::unknown; + read (stream, signature); + read (stream, node_id); read (stream, block_count); boost::endian::big_to_native_inplace (block_count); @@ -1118,6 +1120,9 @@ void nano::telemetry_data::deserialize (nano::stream & stream, uint16_t payload_ read (stream, active_difficulty); boost::endian::big_to_native_inplace (active_difficulty); + version = version_t::v1; + + // Added in V27, will throw if not present uint8_t database_backend_l; read (stream, database_backend_l); database_backend = static_cast (database_backend_l); @@ -1126,6 +1131,8 @@ void nano::telemetry_data::deserialize (nano::stream & stream, uint16_t payload_ read (stream, database_version_minor); read (stream, database_version_patch); + version = version_t::v2; + if (payload_length > size) { read (stream, unknown_data, payload_length - size); @@ -1152,10 +1159,17 @@ void nano::telemetry_data::serialize_without_signature (nano::stream & stream) c write (stream, static_cast> (maker)); write (stream, boost::endian::native_to_big (std::chrono::duration_cast (timestamp.time_since_epoch ()).count ())); write (stream, boost::endian::native_to_big (active_difficulty)); + + if (version == version_t::v1) + { + return; + } + write (stream, static_cast> (database_backend)); write (stream, database_version_major); write (stream, database_version_minor); write (stream, database_version_patch); + write (stream, unknown_data); } diff --git a/nano/node/messages.hpp b/nano/node/messages.hpp index cf49dbeb47..bc74997339 100644 --- a/nano/node/messages.hpp +++ b/nano/node/messages.hpp @@ -328,6 +328,14 @@ telemetry_backend to_telemetry_backend (std::string); class telemetry_data { +public: + enum class version_t + { + unknown = 0, + v1, // Pre V27 + v2, // V27+ + }; + public: // Payload nano::signature signature{ 0 }; nano::account node_id{}; @@ -356,6 +364,9 @@ class telemetry_data // TODO: Is supporting re-serialization necessary? std::vector unknown_data; +private: + version_t version{ version_t::v2 }; + public: void serialize (nano::stream &) const; void deserialize (nano::stream &, uint16_t payload_length);