diff --git a/examples/js_client/hp-client-lib.js b/examples/js_client/hp-client-lib.js index d1b47c21..6d19c6bc 100644 --- a/examples/js_client/hp-client-lib.js +++ b/examples/js_client/hp-client-lib.js @@ -498,8 +498,15 @@ else if (m.type == "stat_response") { statResponseResolvers.forEach(resolver => { resolver({ + hpVersion: m.hp_version, lclSeqNo: m.lcl_seq_no, - lcl_hash: m.lcl_hash + lclHash: m.lcl_hash, + roundTime: m.round_time, + contractExecutionEnabled: m.contract_execution_enabled, + readRequestsEnabled: m.read_requests_enabled, + isFull_history_node: m.is_full_history_node, + currentUnl: m.current_unl, + peers: m.peers }); }) statResponseResolvers = []; diff --git a/src/msg/bson/usrmsg_bson.cpp b/src/msg/bson/usrmsg_bson.cpp index d144ae1a..33ffe1e4 100644 --- a/src/msg/bson/usrmsg_bson.cpp +++ b/src/msg/bson/usrmsg_bson.cpp @@ -1,3 +1,5 @@ +#include "../../conf.hpp" +#include "../../p2p/p2p.hpp" #include "../../pchheader.hpp" #include "../../util/util.hpp" #include "../../hplog.hpp" @@ -16,16 +18,49 @@ namespace msg::usrmsg::bson * "lcl_hash": * } */ + constexpr const size_t MAX_KNOWN_PEERS_INFO = 10; + void create_status_response(std::vector &msg, const uint64_t lcl_seq_no, std::string_view lcl_hash) { jsoncons::bson::bson_bytes_encoder encoder(msg); encoder.begin_object(); encoder.key(msg::usrmsg::FLD_TYPE); encoder.string_value(msg::usrmsg::MSGTYPE_STAT_RESPONSE); + encoder.key(msg::usrmsg::FLD_HP_VERSION); + encoder.string_value(conf::cfg.hp_version); encoder.key(msg::usrmsg::FLD_LCL_SEQ); encoder.int64_value(lcl_seq_no); encoder.key(msg::usrmsg::FLD_LCL_HASH); encoder.byte_string_value(lcl_hash); + encoder.key(msg::usrmsg::FLD_ROUND_TIME); + encoder.uint64_value(conf::cfg.contract.roundtime); + encoder.key(msg::usrmsg::FLD_CONTARCT_EXECUTION_ENABLED); + encoder.bool_value(conf::cfg.contract.execute); + encoder.key(msg::usrmsg::FLD_READ_REQUESTS_ENABLED); + encoder.bool_value(conf::cfg.user.concurrent_read_reqeuests != 0); + encoder.key(msg::usrmsg::FLD_IS_FULL_HISTORY_NODE); + encoder.bool_value(conf::cfg.node.history == conf::HISTORY::FULL); + + encoder.key(msg::usrmsg::FLD_CURRENT_UNL); + encoder.begin_array(); + for (std::string_view unl : conf::cfg.contract.unl) + encoder.byte_string_value(unl); + encoder.end_array(); + encoder.key(msg::usrmsg::FLD_PEERS); + + { + std::scoped_lock lock(p2p::ctx.peer_connections_mutex); + + const size_t max_peers_count = MIN(MAX_KNOWN_PEERS_INFO, p2p::ctx.peer_connections.size()); + size_t count = 1; + + encoder.begin_array(); + // Currently all peers, up to a max of 10 are sent regardless of state. + for (auto peer = p2p::ctx.peer_connections.begin(); peer != p2p::ctx.peer_connections.end() && count <= max_peers_count; peer++, count++) + encoder.string_value(peer->second->known_ipport->host_address + ":" + std::to_string(peer->second->known_ipport->port)); + encoder.end_array(); + } + encoder.end_object(); encoder.flush(); } diff --git a/src/msg/json/usrmsg_json.cpp b/src/msg/json/usrmsg_json.cpp index 4f339962..2ede5a30 100644 --- a/src/msg/json/usrmsg_json.cpp +++ b/src/msg/json/usrmsg_json.cpp @@ -16,6 +16,10 @@ namespace msg::usrmsg::json constexpr const char *SEP_COMMA_NOQUOTE = ",\""; constexpr const char *SEP_COLON_NOQUOTE = "\":"; constexpr const char *DOUBLE_QUOTE = "\""; + constexpr const char *OPEN_SQR_BRACKET = "["; + constexpr const char *CLOSE_SQR_BRACKET = "]"; + + constexpr const size_t MAX_KNOWN_PEERS_INFO = 10; // std::vector overload to concatonate string. std::vector &operator+=(std::vector &vec, std::string_view sv) @@ -136,12 +140,18 @@ namespace msg::usrmsg::json */ void create_status_response(std::vector &msg, const uint64_t lcl_seq_no, std::string_view lcl_hash) { - msg.reserve(256); + const uint16_t msg_length = 406 + (69 * conf::cfg.contract.unl.size()); + + msg.reserve(msg_length); msg += "{\""; msg += msg::usrmsg::FLD_TYPE; msg += SEP_COLON; msg += msg::usrmsg::MSGTYPE_STAT_RESPONSE; msg += SEP_COMMA; + msg += msg::usrmsg::FLD_HP_VERSION; + msg += SEP_COLON; + msg += conf::cfg.hp_version; + msg += SEP_COMMA; msg += msg::usrmsg::FLD_LCL_SEQ; msg += SEP_COLON_NOQUOTE; msg += std::to_string(lcl_seq_no); @@ -149,7 +159,59 @@ namespace msg::usrmsg::json msg += msg::usrmsg::FLD_LCL_HASH; msg += SEP_COLON; msg += util::to_hex(lcl_hash); - msg += "\"}"; + msg += SEP_COMMA; + msg += msg::usrmsg::FLD_ROUND_TIME; + msg += SEP_COLON_NOQUOTE; + msg += std::to_string(conf::cfg.contract.roundtime); + msg += SEP_COMMA_NOQUOTE; + msg += msg::usrmsg::FLD_CONTARCT_EXECUTION_ENABLED; + msg += SEP_COLON_NOQUOTE; + msg += conf::cfg.contract.execute ? "true" : "false"; + msg += SEP_COMMA_NOQUOTE; + msg += msg::usrmsg::FLD_READ_REQUESTS_ENABLED; + msg += SEP_COLON_NOQUOTE; + msg += conf::cfg.user.concurrent_read_reqeuests != 0 ? "true" : "false"; + msg += SEP_COMMA_NOQUOTE; + msg += msg::usrmsg::FLD_IS_FULL_HISTORY_NODE; + msg += SEP_COLON_NOQUOTE; + msg += conf::cfg.node.history == conf::HISTORY::FULL ? "true" : "false"; + msg += SEP_COMMA_NOQUOTE; + msg += msg::usrmsg::FLD_CURRENT_UNL; + msg += SEP_COLON_NOQUOTE; + msg += OPEN_SQR_BRACKET; + + for (auto node = conf::cfg.contract.unl.begin(); node != conf::cfg.contract.unl.end(); node++) + { + msg += DOUBLE_QUOTE + util::to_hex(*node) + DOUBLE_QUOTE; + + if (std::next(node) != conf::cfg.contract.unl.end()) + msg += ","; + } + + msg += CLOSE_SQR_BRACKET; + msg += SEP_COMMA_NOQUOTE; + msg += msg::usrmsg::FLD_PEERS; + msg += SEP_COLON_NOQUOTE; + msg += OPEN_SQR_BRACKET; + + { + std::scoped_lock lock(p2p::ctx.peer_connections_mutex); + + const size_t max_peers_count = MIN(MAX_KNOWN_PEERS_INFO, p2p::ctx.peer_connections.size()); + size_t count = 1; + + // Currently all peers, up to a max of 10 are sent regardless of state. + for (auto peer = p2p::ctx.peer_connections.begin(); peer != p2p::ctx.peer_connections.end() && count <= max_peers_count; peer++, count++) + { + msg += DOUBLE_QUOTE + peer->second->known_ipport->host_address + ":" + std::to_string(peer->second->known_ipport->port) + DOUBLE_QUOTE; + + if (peer != p2p::ctx.peer_connections.end() && count < max_peers_count) + msg += ","; + } + } + + msg += CLOSE_SQR_BRACKET; + msg += "}"; } /** diff --git a/src/msg/usrmsg_common.hpp b/src/msg/usrmsg_common.hpp index a16a7c83..c33f200e 100644 --- a/src/msg/usrmsg_common.hpp +++ b/src/msg/usrmsg_common.hpp @@ -33,6 +33,12 @@ namespace msg::usrmsg constexpr const char *FLD_LCL_SEQ = "lcl_seq_no"; constexpr const char *FLD_STATUS = "status"; constexpr const char *FLD_REASON = "reason"; + constexpr const char *FLD_ROUND_TIME = "round_time"; + constexpr const char *FLD_CONTARCT_EXECUTION_ENABLED = "contract_execution_enabled"; + constexpr const char *FLD_READ_REQUESTS_ENABLED = "read_requests_enabled"; + constexpr const char *FLD_IS_FULL_HISTORY_NODE = "is_full_history_node"; + constexpr const char *FLD_CURRENT_UNL = "current_unl"; + constexpr const char *FLD_PEERS = "peers"; // Message types constexpr const char *MSGTYPE_USER_CHALLENGE = "user_challenge";