From c9f032adcc24a5ffac69409da9e397f156eebdeb Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sun, 25 Oct 2020 18:15:56 +0000 Subject: [PATCH] keep track of peers' peer lists --- src/p2p/net_node.h | 5 ++++- src/p2p/net_node.inl | 21 ++++++++++++++++++++- src/rpc/core_rpc_server.cpp | 20 ++++++++++++++++++++ src/rpc/core_rpc_server.h | 2 ++ src/rpc/core_rpc_server_commands_defs.h | 24 ++++++++++++++++++++++++ utils/python-rpc/framework/daemon.py | 6 ++++++ 6 files changed, 76 insertions(+), 2 deletions(-) diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h index 001559313..836f16de2 100644 --- a/src/p2p/net_node.h +++ b/src/p2p/net_node.h @@ -124,6 +124,7 @@ namespace nodetool uint32_t support_flags; bool m_in_timedsync; std::set sent_addresses; + std::set received_addresses; }; template @@ -274,6 +275,8 @@ namespace nodetool void get_public_peerlist(std::vector& gray, std::vector& white); void get_peerlist(std::vector& gray, std::vector& white); + std::set get_peer_list(const epee::net_utils::network_address &address); + void change_max_out_public_peers(size_t count); uint32_t get_max_out_public_peers() const; void change_max_in_public_peers(size_t count); @@ -347,7 +350,7 @@ namespace nodetool const boost::program_options::variables_map& vm ); bool idle_worker(); - bool handle_remote_peerlist(const std::vector& peerlist, const epee::net_utils::connection_context_base& context); + bool handle_remote_peerlist(const std::vector& peerlist, p2p_connection_context& context); bool get_local_node_data(basic_node_data& node_data, const network_zone& zone); //bool get_local_handshake_data(handshake_data& hshd); diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index 87dd8d047..ceec49836 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -1836,6 +1836,23 @@ namespace nodetool } //----------------------------------------------------------------------------------- template + std::set node_server::get_peer_list(const epee::net_utils::network_address &address) + { + std::set addresses; + for(auto& zone : m_network_zones) + { + zone.second.m_net_server.get_config_object().foreach_connection([&addresses, &address](p2p_connection_context& cntxt) + { + if (cntxt.m_remote_address != address) + return true; + addresses = cntxt.received_addresses; + return false; + }); + } + return addresses; + } + //----------------------------------------------------------------------------------- + template bool node_server::idle_worker() { m_peer_handshake_idle_maker_interval.do_call(boost::bind(&node_server::peer_sync_idle_maker, this)); @@ -1942,7 +1959,7 @@ namespace nodetool } //----------------------------------------------------------------------------------- template - bool node_server::handle_remote_peerlist(const std::vector& peerlist, const epee::net_utils::connection_context_base& context) + bool node_server::handle_remote_peerlist(const std::vector& peerlist, p2p_connection_context& context) { std::vector peerlist_ = peerlist; if(!sanitize_peerlist(peerlist_)) @@ -1960,6 +1977,8 @@ namespace nodetool LOG_DEBUG_CC(context, "REMOTE PEERLIST: remote peerlist size=" << peerlist_.size()); LOG_TRACE_CC(context, "REMOTE PEERLIST: " << ENDL << print_peerlist_to_string(peerlist_)); + for (const auto &e: peerlist_) + context.received_addresses.insert(e.adr); return m_network_zones.at(context.m_remote_address.get_zone()).m_peerlist.merge_peerlist(peerlist_, [this](const peerlist_entry &pe) { return !is_addr_recently_failed(pe.adr); }); } //----------------------------------------------------------------------------------- diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 1f152c786..b831e6451 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -1386,6 +1386,26 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ + bool core_rpc_server::on_get_peer_peer_list(const COMMAND_RPC_GET_PEER_PEER_LIST::request& req, COMMAND_RPC_GET_PEER_PEER_LIST::response& res, const connection_context *ctx) + { + RPC_TRACKER(get_peer_peer_list); + + expect address = net::get_network_address(req.peer, 0); + if (!address) + { + res.status = "Error parsing address"; + return true; + } + + std::set addresses = m_p2p.get_peer_list(*address); + res.peers.reserve(addresses.size()); + for (const auto &e: addresses) + res.peers.push_back(e.str()); + + res.status = CORE_RPC_STATUS_OK; + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ bool core_rpc_server::on_get_public_nodes(const COMMAND_RPC_GET_PUBLIC_NODES::request& req, COMMAND_RPC_GET_PUBLIC_NODES::response& res, const connection_context *ctx) { RPC_TRACKER(get_public_nodes); diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index dcf6b4e4b..37ec4e629 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -118,6 +118,7 @@ namespace cryptonote MAP_URI_AUTO_JON2_IF("/mining_status", on_mining_status, COMMAND_RPC_MINING_STATUS, !m_restricted) MAP_URI_AUTO_JON2_IF("/save_bc", on_save_bc, COMMAND_RPC_SAVE_BC, !m_restricted) MAP_URI_AUTO_JON2_IF("/get_peer_list", on_get_peer_list, COMMAND_RPC_GET_PEER_LIST, !m_restricted) + MAP_URI_AUTO_JON2_IF("/get_peer_peer_list", on_get_peer_peer_list, COMMAND_RPC_GET_PEER_PEER_LIST, !m_restricted) MAP_URI_AUTO_JON2("/get_public_nodes", on_get_public_nodes, COMMAND_RPC_GET_PUBLIC_NODES) MAP_URI_AUTO_JON2_IF("/set_log_hash_rate", on_set_log_hash_rate, COMMAND_RPC_SET_LOG_HASH_RATE, !m_restricted) MAP_URI_AUTO_JON2_IF("/set_log_level", on_set_log_level, COMMAND_RPC_SET_LOG_LEVEL, !m_restricted) @@ -204,6 +205,7 @@ namespace cryptonote bool on_get_net_stats(const COMMAND_RPC_GET_NET_STATS::request& req, COMMAND_RPC_GET_NET_STATS::response& res, const connection_context *ctx = NULL); bool on_save_bc(const COMMAND_RPC_SAVE_BC::request& req, COMMAND_RPC_SAVE_BC::response& res, const connection_context *ctx = NULL); bool on_get_peer_list(const COMMAND_RPC_GET_PEER_LIST::request& req, COMMAND_RPC_GET_PEER_LIST::response& res, const connection_context *ctx = NULL); + bool on_get_peer_peer_list(const COMMAND_RPC_GET_PEER_PEER_LIST::request& req, COMMAND_RPC_GET_PEER_PEER_LIST::response& res, const connection_context *ctx = NULL); bool on_get_public_nodes(const COMMAND_RPC_GET_PUBLIC_NODES::request& req, COMMAND_RPC_GET_PUBLIC_NODES::response& res, const connection_context *ctx = NULL); bool on_set_log_hash_rate(const COMMAND_RPC_SET_LOG_HASH_RATE::request& req, COMMAND_RPC_SET_LOG_HASH_RATE::response& res, const connection_context *ctx = NULL); bool on_set_log_level(const COMMAND_RPC_SET_LOG_LEVEL::request& req, COMMAND_RPC_SET_LOG_LEVEL::response& res, const connection_context *ctx = NULL); diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 8907a63c3..f2ee3864f 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -1215,6 +1215,30 @@ namespace cryptonote typedef epee::misc_utils::struct_init response; }; + struct COMMAND_RPC_GET_PEER_PEER_LIST + { + struct request_t: public rpc_request_base + { + std::string peer; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(peer) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; + + struct response_t: public rpc_response_base + { + std::vector peers; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_PARENT(rpc_response_base) + KV_SERIALIZE(peers) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; + }; + struct public_node { std::string host; diff --git a/utils/python-rpc/framework/daemon.py b/utils/python-rpc/framework/daemon.py index 435bc93f8..54920c8cb 100644 --- a/utils/python-rpc/framework/daemon.py +++ b/utils/python-rpc/framework/daemon.py @@ -429,6 +429,12 @@ class Daemon(object): } return self.rpc.send_request('/get_peer_list', get_peer_list) + def get_peer_peer_list(self, peer): + get_peer_peer_list = { + 'peer': peer + } + return self.rpc.send_request('/get_peer_peer_list', get_peer_peer_list) + def set_log_hash_rate(self, visible): set_log_hash_rate = { 'visible': visible,