From dfc487d5d50edd46f8a305529a0e72764adc119a Mon Sep 17 00:00:00 2001
From: "pavel.uhanov" <pavel.uhanov@demlabs.net>
Date: Thu, 20 Mar 2025 12:44:28 +0300
Subject: [PATCH] [*] add cmd data collect

---
 dap-sdk                                  |  2 +-
 modules/net/dap_chain_node_cli.c         |  1 +
 modules/net/dap_chain_node_rpc.c         | 32 ++++++++++++++++++++----
 modules/net/include/dap_chain_node_rpc.h | 25 ++++++++++--------
 4 files changed, 44 insertions(+), 16 deletions(-)

diff --git a/dap-sdk b/dap-sdk
index ff8478aa04..8bf745b398 160000
--- a/dap-sdk
+++ b/dap-sdk
@@ -1 +1 @@
-Subproject commit ff8478aa04fa94540016fee0038db4b63965d0d1
+Subproject commit 8bf745b39864481042e243e0347f16e802c81ecb
diff --git a/modules/net/dap_chain_node_cli.c b/modules/net/dap_chain_node_cli.c
index dc230b60bf..93a8c23204 100644
--- a/modules/net/dap_chain_node_cli.c
+++ b/modules/net/dap_chain_node_cli.c
@@ -394,4 +394,5 @@ void dap_chain_node_cli_delete(void)
     dap_cli_server_deinit();
     // deinit client for handshake
     dap_chain_node_client_deinit();
+    dap_chain_node_rpc_deinit();
 }
diff --git a/modules/net/dap_chain_node_rpc.c b/modules/net/dap_chain_node_rpc.c
index 0fec020f5a..aafd0fa739 100644
--- a/modules/net/dap_chain_node_rpc.c
+++ b/modules/net/dap_chain_node_rpc.c
@@ -36,12 +36,20 @@ typedef enum {
     RPC_ROLE_ROOT
 } rpc_role_t;
 
+struct cmd_call_stat {
+    atomic_int_fast32_t count;
+    atomic_int_fast64_t time;
+};
+
 static const uint64_t s_timer_update_states_info = 10 /*sec*/ * 1000;
 static const char s_rpc_server_states_group[] = "rpc.states";
 static const char s_rpc_node_list_group[] = "rpc.list";
 static dap_global_db_cluster_t *s_rpc_server_states_cluster = NULL;
 static dap_global_db_cluster_t *s_rpc_node_list_cluster = NULL;
 
+
+static struct cmd_call_stat *s_cmd_call_stat = NULL;
+
 DAP_STATIC_INLINE s_get_role_from_str(const char *a_str)
 {
     if (!a_str) return RPC_ROLE_INVALID;
@@ -52,9 +60,11 @@ DAP_STATIC_INLINE s_get_role_from_str(const char *a_str)
     return RPC_ROLE_INVALID;
 }
 
-static void s_collect_state_info(int16_t a_cmd_num, bool a_start_measure)
+static void s_collect_cmd_stat_info(int16_t a_cmd_num, int64_t a_call_time)
 {
-
+    dap_return_if_pass(a_cmd_num >= DAP_CHAIN_NODE_CLI_CMD_ID_TOTAL);
+    atomic_fetch_add(&(s_cmd_call_stat + a_cmd_num)->count, 1);
+    atomic_fetch_add(&(s_cmd_call_stat + a_cmd_num)->time, a_call_time);
 }
 
 /**
@@ -69,6 +79,11 @@ static void s_update_node_rpc_states_info(UNUSED_ARG void *a_arg)
     l_info->links_count = dap_stream_get_links_count();
     l_info->cli_thread_count = dap_cli_get_cmd_thread_count();
     sysinfo(&l_info->sysinfo);
+    for(int16_t i = 0; i < DAP_CHAIN_NODE_CLI_CMD_ID_TOTAL; ++i) {
+        int32_t l_count = atomic_load(&(s_cmd_call_stat + i)->count);
+        int64_t l_time = atomic_load(&(s_cmd_call_stat + i)->time);
+        l_info->cmd_info.time_stat[i] = l_count ? l_time / l_count : 0;
+    }
 
     const char *l_node_addr_str = dap_stream_node_addr_to_str_static(l_info->address);
     dap_global_db_set_sync(s_rpc_server_states_group, l_node_addr_str, l_info, sizeof(dap_chain_node_rpc_states_info_t), false);
@@ -115,16 +130,23 @@ void dap_chain_node_rpc_init(dap_config_t *a_cfg)
             return;
         }
         if (l_role == RPC_ROLE_SERVER) {
-            if (dap_proc_thread_timer_add(NULL, s_update_node_rpc_states_info, NULL, s_timer_update_states_info))
+            if (dap_proc_thread_timer_add(NULL, s_update_node_rpc_states_info, NULL, s_timer_update_states_info)) {
                 log_it(L_ERROR, "Can't activate timer on node states update");
-            else
-                dap_cli_server_statistic_callback_add(s_collect_state_info);
+            } else {
+                s_cmd_call_stat = DAP_NEW_Z_COUNT_RET_IF_FAIL(struct cmd_call_stat, DAP_CHAIN_NODE_CLI_CMD_ID_TOTAL);
+                dap_cli_server_statistic_callback_add(s_collect_cmd_stat_info);
+            }
         }
     }
     if (l_role == RPC_ROLE_ROOT && !dap_chain_node_rpc_is_my_node_authorized())
         log_it(L_WARNING, "Your addres not finded in authorized rpc node list");
 }
 
+void dap_chain_node_rpc_deinit()
+{
+    DAP_DELETE(s_cmd_call_stat);
+}
+
 /**
  * @brief get states rpc info about current
  * @param a_arg - pointer to callback arg
diff --git a/modules/net/include/dap_chain_node_rpc.h b/modules/net/include/dap_chain_node_rpc.h
index dbaee77aaa..b382be9d28 100644
--- a/modules/net/include/dap_chain_node_rpc.h
+++ b/modules/net/include/dap_chain_node_rpc.h
@@ -20,17 +20,22 @@
  */
 #include <sys/sysinfo.h>
 #include "dap_chain_node.h"
+#include "dap_chain_node_cli_cmd.h"
 #include "dap_config.h"
 
- typedef struct dap_chain_node_rpc_states_info {
-    uint32_t version;
-    dap_chain_node_addr_t address;
-    uint32_t location;
-    uint32_t links_count;
-    uint32_t cli_thread_count;
-    struct sysinfo sysinfo;
-    uint32_t cmd_data_size;
-    uint8_t cmd_data[];
+typedef struct dap_chain_node_rpc_cmd_states_info {
+   int16_t count;
+   int64_t time_stat[DAP_CHAIN_NODE_CLI_CMD_ID_TOTAL];
+} DAP_ALIGN_PACKED dap_chain_node_rpc_cmd_states_info_t;
+
+typedef struct dap_chain_node_rpc_states_info {
+   uint32_t version;
+   dap_chain_node_addr_t address;
+   uint32_t location;
+   uint32_t links_count;
+   uint32_t cli_thread_count;
+   struct sysinfo sysinfo;
+   dap_chain_node_rpc_cmd_states_info_t cmd_info;
 } DAP_ALIGN_PACKED dap_chain_node_rpc_states_info_t;
 
  void dap_chain_node_rpc_init(dap_config_t *a_cfg);
@@ -40,5 +45,5 @@
 
  DAP_STATIC_INLINE size_t dap_chain_node_rpc_get_states_info_size(dap_chain_node_rpc_states_info_t *a_info)
  {
-    return a_info ? sizeof(dap_chain_node_rpc_states_info_t) + a_info->cmd_data_size : 0;
+    return a_info ? sizeof(dap_chain_node_rpc_states_info_t) : 0;
  }
\ No newline at end of file
-- 
GitLab