From 426ca5a22bd635fde482a0ad626dca5d94e73a9b Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 25 Sep 2024 04:13:41 +0200 Subject: [PATCH] p2p: clients with outdated versions now rejected by p2p upon hf activation as well (+tied to hf min build number) --- src/currency_core/connection_context.h | 2 + src/currency_core/currency_core.cpp | 1 + .../currency_protocol_defs.h | 4 +- .../currency_protocol_handler.h | 13 ++-- .../currency_protocol_handler.inl | 68 ++++++++++++++++--- .../currency_protocol_handler_common.h | 1 + src/p2p/net_node.inl | 4 +- 7 files changed, 77 insertions(+), 16 deletions(-) diff --git a/src/currency_core/connection_context.h b/src/currency_core/connection_context.h index 6c242cc1..1320619c 100644 --- a/src/currency_core/connection_context.h +++ b/src/currency_core/connection_context.h @@ -51,6 +51,8 @@ namespace currency uint64_t m_last_response_height; int64_t m_time_delta; std::string m_remote_version; + int m_build_number = 0; + private: template friend class t_currency_protocol_handler; uncopybale_currency_context m_priv; diff --git a/src/currency_core/currency_core.cpp b/src/currency_core/currency_core.cpp index 1c15498b..8d29c38d 100644 --- a/src/currency_core/currency_core.cpp +++ b/src/currency_core/currency_core.cpp @@ -552,6 +552,7 @@ namespace currency if (hardfork_id_for_prev_block != hardfork_id_for_curr_block) { LOG_PRINT_GREEN("Hardfork " << hardfork_id_for_curr_block << " has been activated after the block at height " << h, LOG_LEVEL_0); + m_pprotocol->on_hardfork_activated(hardfork_id_for_curr_block); } } diff --git a/src/currency_protocol/currency_protocol_defs.h b/src/currency_protocol/currency_protocol_defs.h index 2a0eead6..b1ee93bc 100644 --- a/src/currency_protocol/currency_protocol_defs.h +++ b/src/currency_protocol/currency_protocol_defs.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2018 Zano Project +// Copyright (c) 2014-2024 Zano Project // Copyright (c) 2014-2018 The Louisdor Project // Copyright (c) 2012-2013 The Cryptonote developers // Distributed under the MIT/X11 software license, see the accompanying @@ -135,7 +135,7 @@ namespace currency struct CORE_SYNC_DATA { - uint64_t current_height; + uint64_t current_height; // height of the top block + 1 crypto::hash top_id; uint64_t last_checkpoint_height; uint64_t core_time; diff --git a/src/currency_protocol/currency_protocol_handler.h b/src/currency_protocol/currency_protocol_handler.h index 1e420919..c21ac71a 100644 --- a/src/currency_protocol/currency_protocol_handler.h +++ b/src/currency_protocol/currency_protocol_handler.h @@ -74,6 +74,10 @@ namespace currency //----------------------------------------------------------------------------------- void set_to_debug_mode(uint32_t ip); + bool is_remote_client_version_allowed(int build_number, size_t min_allowed_build_number = SIZE_MAX) const; + bool is_remote_client_version_allowed(const std::string& client_version) const; + void check_all_client_versions_are_okay(); + private: //----------------- commands handlers ---------------------------------------------- int handle_notify_new_block(int command, NOTIFY_NEW_BLOCK::request& arg, currency_connection_context& context); @@ -86,11 +90,12 @@ namespace currency - //----------------- i_bc_protocol_layout --------------------------------------- - virtual bool relay_block(NOTIFY_NEW_BLOCK::request& arg, currency_connection_context& exclude_context); - virtual bool relay_transactions(NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request& arg, currency_connection_context& exclude_context); + //----------------- i_currency_protocol --------------------------------------- + virtual bool relay_block(NOTIFY_NEW_BLOCK::request& arg, currency_connection_context& exclude_context) override; + virtual bool relay_transactions(NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request& arg, currency_connection_context& exclude_context) override; + virtual void on_hardfork_activated(size_t hardfork_id) override; //---------------------------------------------------------------------------------- - //bool get_payload_sync_data(HANDSHAKE_DATA::request& hshd, currency_connection_context& context); + bool request_missing_objects(currency_connection_context& context, bool check_having_blocks); bool on_connection_synchronized(); void relay_que_worker(); diff --git a/src/currency_protocol/currency_protocol_handler.inl b/src/currency_protocol/currency_protocol_handler.inl index e6d75eb2..3d070fb4 100644 --- a/src/currency_protocol/currency_protocol_handler.inl +++ b/src/currency_protocol/currency_protocol_handler.inl @@ -1,13 +1,14 @@ -// Copyright (c) 2014-2018 Zano Project +// Copyright (c) 2014-2024 Zano Project // Copyright (c) 2014-2018 The Louisdor Project // Copyright (c) 2012-2013 The Cryptonote developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. - #include +#include "currency_protocol_handler.h" #include "currency_core/currency_format_utils.h" #include "profile_tools.h" #include + namespace currency { @@ -96,7 +97,7 @@ namespace currency ss << std::setw(29) << std::left << "Remote Host" << std::setw(20) << "Peer id" - << std::setw(25) << "Recv/Sent (idle,sec)" + << std::setw(27) << "Recv/Sent (idle,sec)" << std::setw(25) << "State" << std::setw(20) << "Livetime" << std::setw(20) << "Client version" << ENDL; @@ -110,7 +111,7 @@ namespace currency conn_ss << std::setw(29) << std::left << std::string(cntxt.m_is_income ? "[INC]":"[OUT]") + epst::get_ip_string_from_int32(cntxt.m_remote_ip) + ":" + std::to_string(cntxt.m_remote_port) << std::setw(20) << std::hex << peer_id - << std::setw(25) << std::to_string(cntxt.m_recv_cnt)+ "(" + std::to_string(time(NULL) - cntxt.m_last_recv) + ")" + "/" + std::to_string(cntxt.m_send_cnt) + "(" + std::to_string(time(NULL) - cntxt.m_last_send) + ")" + << std::setw(27) << std::to_string(cntxt.m_recv_cnt)+ "(" + std::to_string(time(NULL) - cntxt.m_last_recv) + ")" + "/" + std::to_string(cntxt.m_send_cnt) + "(" + std::to_string(time(NULL) - cntxt.m_last_send) + ")" << std::setw(25) << get_protocol_state_string(cntxt.m_state) << std::setw(20) << epee::misc_utils::get_time_interval_string(livetime) << std::setw(20) << cntxt.m_remote_version @@ -129,9 +130,12 @@ namespace currency template bool t_currency_protocol_handler::process_payload_sync_data(const CORE_SYNC_DATA& hshd, currency_connection_context& context, bool is_inital) { - - context.m_remote_version = hshd.client_version; + if (!tools::parse_client_version_build_number(context.m_remote_version, context.m_build_number)) + { + LOG_PRINT_RED_L0("Couldn't parse remote node's version: " << context.m_remote_version << ". Connection will be dropped."); + return false; + } if(context.m_state == currency_connection_context::state_befor_handshake && !is_inital) return true; @@ -989,7 +993,7 @@ namespace currency //------------------------------------------------------------------------------------------------------------------------ template bool t_currency_protocol_handler::relay_transactions(NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request& arg, currency_connection_context& exclude_context) - { + { #ifdef ASYNC_RELAY_MODE { CRITICAL_REGION_LOCAL(m_relay_que_lock); @@ -1003,4 +1007,52 @@ namespace currency return relay_post_notify(arg, exclude_context); #endif } -} + //------------------------------------------------------------------------------------------------------------------------ + template + void t_currency_protocol_handler::on_hardfork_activated(size_t hardfork_id) + { + check_all_client_versions_are_okay(); + } + //------------------------------------------------------------------------------------------------------------------------ + template + bool t_currency_protocol_handler::is_remote_client_version_allowed(int build_number, size_t min_allowed_build_number /*= SIZE_MAX*/) const + { + if (min_allowed_build_number == SIZE_MAX) + min_allowed_build_number = m_core.get_blockchain_storage().get_core_runtime_config().get_min_allowed_build_version_for_height(m_core.get_top_block_height() + 1); + + if (build_number < min_allowed_build_number) + return false; + + return true; + } + //------------------------------------------------------------------------------------------------------------------------ + template + bool t_currency_protocol_handler::is_remote_client_version_allowed(const std::string& client_version) const + { + int major = -1, minor = -1, revision = -1, build_number = -1; + std::string commit_id; + bool dirty = false; + if (!tools::parse_client_version(client_version, major, minor, revision, build_number, commit_id, dirty)) + return false; + + return is_remote_client_version_allowed(build_number); + } + //------------------------------------------------------------------------------------------------------------------------ + template + void t_currency_protocol_handler::check_all_client_versions_are_okay() + { + size_t min_allowed_build_number = m_core.get_blockchain_storage().get_core_runtime_config().get_min_allowed_build_version_for_height(m_core.get_top_block_height() + 1); + + m_p2p->for_each_connection([&](const connection_context& cc, nodetool::peerid_type peer_id) + { + if (!is_remote_client_version_allowed(cc.m_build_number, min_allowed_build_number)) + { + LOG_PRINT_CC_YELLOW(cc, "client's build number is " << cc.m_build_number << ", which is absolutely not okay in the current hardfork era, prompting us to adjust our connections accordingly.", LOG_LEVEL_0); + m_p2p->drop_connection(cc); + } + return true; // = continue + }); + } + + +} // namespace currency diff --git a/src/currency_protocol/currency_protocol_handler_common.h b/src/currency_protocol/currency_protocol_handler_common.h index d07153f5..ba640896 100644 --- a/src/currency_protocol/currency_protocol_handler_common.h +++ b/src/currency_protocol/currency_protocol_handler_common.h @@ -18,6 +18,7 @@ namespace currency { virtual bool relay_block(NOTIFY_NEW_BLOCK::request& arg, currency_connection_context& exclude_context)=0; virtual bool relay_transactions(NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request& arg, currency_connection_context& exclude_context)=0; + virtual void on_hardfork_activated(size_t hardfork_id) {} //virtual bool request_objects(NOTIFY_REQUEST_GET_OBJECTS::request& arg, currency_connection_context& context)=0; }; diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index 46a39ee5..70b906dc 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -523,7 +523,7 @@ namespace nodetool return; } - if (!tools::check_remote_client_version(rsp.payload_data.client_version)) + if (!m_payload_handler.is_remote_client_version_allowed(rsp.payload_data.client_version)) { LOG_PRINT_CC_YELLOW(context, "COMMAND_HANDSHAKE Failed, wrong client version: " << rsp.payload_data.client_version << ", closing connection.", LOG_LEVEL_1); return; @@ -1391,7 +1391,7 @@ namespace nodetool return 1; } - if (!tools::check_remote_client_version(arg.payload_data.client_version)) + if (!m_payload_handler.is_remote_client_version_allowed(arg.payload_data.client_version)) { LOG_PRINT_CCONTEXT_L2("COMMAND_HANDSHAKE: wrong client version: " << arg.payload_data.client_version << ", closing connection."); drop_connection(context);