From 90641e0849c632335ea450e56d1f219dcc6e37de Mon Sep 17 00:00:00 2001 From: Ravin Perera <33562092+ravinsp@users.noreply.github.com> Date: Tue, 16 Feb 2021 16:20:19 +0530 Subject: [PATCH] Persist discovered peers to config. (#246) --- src/conf.cpp | 15 +++++++++++++++ src/conf.hpp | 10 ++++++---- src/msg/fbuf/p2pmsg_helpers.cpp | 4 ++-- src/msg/fbuf/p2pmsg_helpers.hpp | 4 ++-- src/p2p/p2p.cpp | 10 +++++++++- src/p2p/p2p.hpp | 2 +- src/p2p/peer_comm_server.cpp | 6 +++--- src/p2p/peer_comm_server.hpp | 4 ++-- src/p2p/peer_comm_session.hpp | 2 +- 9 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/conf.cpp b/src/conf.cpp index 646f9148..f4544a26 100644 --- a/src/conf.cpp +++ b/src/conf.cpp @@ -789,6 +789,21 @@ namespace conf return 0; } + /** + * Persists the specified known peers to the config file. + */ + int persist_known_peers_config(const std::vector &peers) + { + if (peers.empty()) + return 0; + + const size_t max_count = conf::cfg.mesh.max_known_connections == 0 + ? peers.size() + : MIN(peers.size(), conf::cfg.mesh.max_known_connections); + cfg.mesh.known_peers = std::vector(peers.begin(), peers.begin() + max_count); + return write_config(cfg); + } + /** * Locks the config file. If already locked means there's another hpcore instance running in the same directory. * If so, log error and return, Otherwise lock the config. diff --git a/src/conf.hpp b/src/conf.hpp index 89eb807b..009ef8b1 100644 --- a/src/conf.hpp +++ b/src/conf.hpp @@ -12,17 +12,17 @@ namespace conf constexpr size_t CONCURRENT_READ_REQUEST_MAX_LIMIT = 32; // Struct to represent ip and port of the peer. - struct ip_port_prop + struct peer_ip_port { std::string host_address; uint16_t port; - bool operator==(ip_port_prop ip_port) + bool operator==(const peer_ip_port &ip_port) { return host_address == ip_port.host_address && port == ip_port.port; } - bool operator!=(ip_port_prop ip_port) + bool operator!=(const peer_ip_port &ip_port) { return !(host_address == ip_port.host_address && port == ip_port.port); } @@ -33,7 +33,7 @@ namespace conf // Later it will be updated according to the capacity anouncement from the peers. struct peer_properties { - ip_port_prop ip_port; + peer_ip_port ip_port; int16_t available_capacity = -1; uint64_t timestamp = 0; }; @@ -234,6 +234,8 @@ namespace conf int apply_patch_config(std::string_view hpfs_session_name); + int persist_known_peers_config(const std::vector &peers); + int set_config_lock(); int release_config_lock(); diff --git a/src/msg/fbuf/p2pmsg_helpers.cpp b/src/msg/fbuf/p2pmsg_helpers.cpp index 1103fbcb..fa481d1d 100644 --- a/src/msg/fbuf/p2pmsg_helpers.cpp +++ b/src/msg/fbuf/p2pmsg_helpers.cpp @@ -670,7 +670,7 @@ namespace msg::fbuf::p2pmsg * @param skipping_peer Peer that does not need to be sent. * @param lcl Lcl value to be passed in the container message. */ - void create_msg_from_peer_list_response(flatbuffers::FlatBufferBuilder &container_builder, const std::vector &peers, const std::optional &skipping_ip_port, std::string_view lcl) + void create_msg_from_peer_list_response(flatbuffers::FlatBufferBuilder &container_builder, const std::vector &peers, const std::optional &skipping_ip_port, std::string_view lcl) { flatbuffers::FlatBufferBuilder builder(1024); @@ -864,7 +864,7 @@ namespace msg::fbuf::p2pmsg * @param skipping_peer Peer that does not need to be sent. */ const flatbuffers::Offset>> - peer_propertiesvector_to_flatbuf_peer_propertieslist(flatbuffers::FlatBufferBuilder &builder, const std::vector &peers, const std::optional &skipping_ip_port) + peer_propertiesvector_to_flatbuf_peer_propertieslist(flatbuffers::FlatBufferBuilder &builder, const std::vector &peers, const std::optional &skipping_ip_port) { std::vector> fbvec; fbvec.reserve(peers.size()); diff --git a/src/msg/fbuf/p2pmsg_helpers.hpp b/src/msg/fbuf/p2pmsg_helpers.hpp index 0e35801d..cef83e9a 100644 --- a/src/msg/fbuf/p2pmsg_helpers.hpp +++ b/src/msg/fbuf/p2pmsg_helpers.hpp @@ -76,7 +76,7 @@ namespace msg::fbuf::p2pmsg void create_msg_from_peer_list_request(flatbuffers::FlatBufferBuilder &container_builder, std::string_view lcl); - void create_msg_from_peer_list_response(flatbuffers::FlatBufferBuilder &container_builder, const std::vector &peers, const std::optional &skipping_ip_port, std::string_view lcl); + void create_msg_from_peer_list_response(flatbuffers::FlatBufferBuilder &container_builder, const std::vector &peers, const std::optional &skipping_ip_port, std::string_view lcl); //---Conversion helpers from flatbuffers data types to std data types---// @@ -98,7 +98,7 @@ namespace msg::fbuf::p2pmsg historyledgermap_to_flatbuf_historyledgermap(flatbuffers::FlatBufferBuilder &builder, const std::map &map); const flatbuffers::Offset>> - peer_propertiesvector_to_flatbuf_peer_propertieslist(flatbuffers::FlatBufferBuilder &builder, const std::vector &peers, const std::optional &skipping_ip_port); + peer_propertiesvector_to_flatbuf_peer_propertieslist(flatbuffers::FlatBufferBuilder &builder, const std::vector &peers, const std::optional &skipping_ip_port); void flatbuf_hpfsfshashentry_to_hpfsfshashentry(std::unordered_map &fs_entries, const flatbuffers::Vector> *fhashes); diff --git a/src/p2p/p2p.cpp b/src/p2p/p2p.cpp index e5f6a147..449bcc6b 100644 --- a/src/p2p/p2p.cpp +++ b/src/p2p/p2p.cpp @@ -44,7 +44,15 @@ namespace p2p void deinit() { if (init_success) + { + // Persist latest known peers information to config before the peer server is stopped. + { + std::scoped_lock lock(ctx.server->req_known_remotes_mutex); + conf::persist_known_peers_config(ctx.server->req_known_remotes); + } + ctx.server->stop(); + } } int start_peer_connections() @@ -325,7 +333,7 @@ namespace p2p * @param available_capacity Available capacity of the known peer, -1 if number of connections is unlimited. * @param timestamp Capacity announced time. */ - void update_known_peer_available_capacity(const conf::ip_port_prop &ip_port, const int16_t available_capacity, const uint64_t ×tamp) + void update_known_peer_available_capacity(const conf::peer_ip_port &ip_port, const int16_t available_capacity, const uint64_t ×tamp) { std::scoped_lock lock(ctx.server->req_known_remotes_mutex); diff --git a/src/p2p/p2p.hpp b/src/p2p/p2p.hpp index f1e0b47c..aba7433d 100644 --- a/src/p2p/p2p.hpp +++ b/src/p2p/p2p.hpp @@ -183,7 +183,7 @@ namespace p2p void send_peer_list_request(); - void update_known_peer_available_capacity(const conf::ip_port_prop &ip_port, const int16_t available_capacity, const uint64_t ×tamp); + void update_known_peer_available_capacity(const conf::peer_ip_port &ip_port, const int16_t available_capacity, const uint64_t ×tamp); void merge_peer_list(const std::vector &peers); diff --git a/src/p2p/peer_comm_server.cpp b/src/p2p/peer_comm_server.cpp index 5f62159a..d1659b3f 100644 --- a/src/p2p/peer_comm_server.cpp +++ b/src/p2p/peer_comm_server.cpp @@ -16,9 +16,9 @@ namespace p2p peer_comm_server::peer_comm_server(const uint16_t port, const uint64_t (&metric_thresholds)[5], const uint64_t max_msg_size, const uint64_t max_in_connections, const uint64_t max_in_connections_per_host, - std::vector &req_known_remotes) + const std::vector &req_known_remotes) : comm::comm_server("Peer", port, metric_thresholds, max_msg_size, max_in_connections, max_in_connections_per_host), - req_known_remotes(req_known_remotes) + req_known_remotes(req_known_remotes) // Copy over known peers into internal collection. { } @@ -115,7 +115,7 @@ namespace p2p void peer_comm_server::maintain_known_connections() { // Find already connected known remote parties list. - std::vector known_remotes; + std::vector known_remotes; { std::scoped_lock lock(sessions_mutex); diff --git a/src/p2p/peer_comm_server.hpp b/src/p2p/peer_comm_server.hpp index 87b51434..30e7480d 100644 --- a/src/p2p/peer_comm_server.hpp +++ b/src/p2p/peer_comm_server.hpp @@ -30,10 +30,10 @@ namespace p2p public: std::atomic known_remote_count = 0; std::mutex req_known_remotes_mutex; - std::vector &req_known_remotes; + std::vector req_known_remotes; peer_comm_server(const uint16_t port, const uint64_t (&metric_thresholds)[5], const uint64_t max_msg_size, const uint64_t max_in_connections, const uint64_t max_in_connections_per_host, - std::vector &req_known_remotes); + const std::vector &req_known_remotes); }; } // namespace p2p diff --git a/src/p2p/peer_comm_session.hpp b/src/p2p/peer_comm_session.hpp index 0d51d9da..7b9241c9 100644 --- a/src/p2p/peer_comm_session.hpp +++ b/src/p2p/peer_comm_session.hpp @@ -21,7 +21,7 @@ namespace p2p void handle_on_verified(); public: - std::optional known_ipport; // A known ip/port information that matches with our peer list configuration. + std::optional known_ipport; // A known ip/port information that matches with our peer list configuration. bool need_consensus_msg_forwarding = false; // Holds whether this node requires consensus message forwarding. bool is_unl = false; // Whether this session's pubkey is in unl list. uint16_t reported_roundtime = 0; // Initial roundtime reported by this peer on peer challenge.