From 6ab71469ee9438715d4d16c3a96c3ee542ebd76b Mon Sep 17 00:00:00 2001
From: "roman.padenkov" <roman.padenkov@demlabs.net>
Date: Tue, 30 May 2023 10:26:04 +0000
Subject: [PATCH] hotfix-8869

---
 modules/net/dap_chain_net.c          | 14 ++++++----
 modules/net/dap_chain_net_balancer.c | 41 ++++++++++++++--------------
 modules/net/include/dap_chain_net.h  |  4 ++-
 modules/net/include/dap_chain_node.h |  2 +-
 4 files changed, 34 insertions(+), 27 deletions(-)

diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index afb2be7b76..5d88eb0608 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -195,6 +195,7 @@ typedef struct dap_chain_net_pvt{
     uint16_t *gdb_sync_nodes_links_ports;
 
     uint16_t seed_aliases_count;
+    struct in_addr *seed_nodes_addrs_v4;
 
     dap_chain_net_state_t state;
     dap_chain_net_state_t state_target;
@@ -594,7 +595,7 @@ static void s_gbd_history_callback_notify(dap_global_db_context_t *a_context, da
     }
 }
 
-static dap_chain_node_info_t *s_get_balancer_link_from_cfg(dap_chain_net_t *a_net)
+dap_chain_node_info_t *dap_get_balancer_link_from_cfg(dap_chain_net_t *a_net)
 {
     dap_chain_net_pvt_t *l_net_pvt = a_net ? PVT(a_net) : NULL;
     if(!l_net_pvt) return NULL;
@@ -850,7 +851,7 @@ static void s_node_link_callback_disconnected(dap_chain_node_client_t *a_node_cl
         if (!l_net_pvt->only_static_links) {
             size_t l_current_links_prepared = HASH_COUNT(l_net_pvt->net_links);
             for (size_t i = l_current_links_prepared; i < l_net_pvt->max_links_count ; i++) {
-                dap_chain_node_info_t *l_link_node_info = s_get_balancer_link_from_cfg(l_net);
+                dap_chain_node_info_t *l_link_node_info = dap_get_balancer_link_from_cfg(l_net);
                 if (l_link_node_info) {
                     if (!s_new_balancer_link_request(l_net, 1))
                         log_it(L_ERROR, "Can't process node info balancer request");
@@ -1100,6 +1101,7 @@ static bool s_new_balancer_link_request(dap_chain_net_t *a_net, int a_link_repla
     dap_chain_node_info_t *l_link_full_node = dap_chain_net_balancer_get_node(a_net->pub.name);
     if(l_link_full_node)
     {
+        log_it(L_DEBUG, "Network LOCAL balancer issues ip %s",inet_ntoa(l_link_full_node->hdr.ext_addr_v4));
         pthread_rwlock_rdlock(&PVT(a_net)->states_lock);
         s_net_link_add(a_net, l_link_full_node);
         DAP_DELETE(l_link_full_node);
@@ -1109,7 +1111,7 @@ static bool s_new_balancer_link_request(dap_chain_net_t *a_net, int a_link_repla
         pthread_rwlock_unlock(&PVT(a_net)->states_lock);
         return false;
     }
-    dap_chain_node_info_t *l_link_node_info = s_get_balancer_link_from_cfg(a_net);
+    dap_chain_node_info_t *l_link_node_info = dap_get_balancer_link_from_cfg(a_net);
     if (!l_link_node_info)
         return false;
     char l_node_addr_str[INET_ADDRSTRLEN] = {};
@@ -1169,7 +1171,7 @@ static void s_prepare_links_from_balancer(dap_chain_net_t *a_net)
     for (size_t l_cur_links_count = 0, n = 0; l_cur_links_count < l_max_links_count; n++) {
         if (n > 1000) // It's a problem with link prepare
             break;
-        dap_chain_node_info_t *l_link_node_info = s_get_balancer_link_from_cfg(a_net);
+        dap_chain_node_info_t *l_link_node_info = dap_get_balancer_link_from_cfg(a_net);
         if (!l_link_node_info)
             continue;
         // Start connect to link hubs
@@ -2382,6 +2384,7 @@ int s_net_init(const char * a_net_name, uint16_t a_acl_idx)
 
         log_it (L_DEBUG, "Read %u aliases, %u address and %u ipv4 addresses, check them",
                 l_net_pvt->seed_aliases_count,l_seed_nodes_addrs_len, l_seed_nodes_ipv4_len );
+        PVT(l_net)->seed_nodes_addrs_v4 = DAP_NEW_SIZE(struct in_addr, l_net_pvt->seed_aliases_count * sizeof(struct in_addr));
         // save new nodes from cfg file to db
         for ( size_t i = 0; i < PVT(l_net)->seed_aliases_count &&
                             i < l_seed_nodes_addrs_len &&
@@ -2414,6 +2417,7 @@ int s_net_init(const char * a_net_name, uint16_t a_acl_idx)
                     struct in_addr *l_res = (struct in_addr *)&l_sa;
                     log_it(L_NOTICE, "Resolved %s to %s (ipv4)", l_seed_nodes_hostnames[i], inet_ntoa(*l_res));
                     l_node_info.hdr.ext_addr_v4.s_addr = l_res->s_addr;
+                    l_net_pvt->seed_nodes_addrs_v4[i].s_addr = l_res->s_addr;
                 } else {
                     log_it(L_ERROR, "%s", gai_strerror(l_ret_code));
                 }
@@ -3095,7 +3099,7 @@ dap_list_t* dap_chain_net_get_node_list_cfg(dap_chain_net_t * a_net)
     dap_chain_net_pvt_t *l_pvt_net = PVT(a_net);
     for(size_t i=0; i < l_pvt_net->seed_aliases_count;i++)
     {
-        l_node_list = dap_list_append(l_node_list, &l_pvt_net->node_info[i]);
+        l_node_list = dap_list_append(l_node_list, &l_pvt_net->seed_nodes_addrs_v4[i]);
     }
     return l_node_list;
 }
diff --git a/modules/net/dap_chain_net_balancer.c b/modules/net/dap_chain_net_balancer.c
index a3a90668f5..b21a20d888 100644
--- a/modules/net/dap_chain_net_balancer.c
+++ b/modules/net/dap_chain_net_balancer.c
@@ -29,7 +29,7 @@ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/lic
 #define LOG_TAG "dap_chain_net_balancer"
 dap_chain_node_info_t *dap_chain_net_balancer_get_node(const char *a_net_name)
 {
-    dap_list_t *l_node_list = NULL,*l_objs_list = NULL;
+    dap_list_t *l_node_addr_list = NULL,*l_objs_list = NULL;
     dap_chain_net_t *l_net = dap_chain_net_by_name(a_net_name);
     if (l_net == NULL) {
         uint16_t l_nets_count;
@@ -48,24 +48,32 @@ dap_chain_node_info_t *dap_chain_net_balancer_get_node(const char *a_net_name)
     l_objs = dap_global_db_get_all_sync(l_net->pub.gdb_nodes, &l_nodes_count);
     if (!l_nodes_count || !l_objs)
         return NULL;
-    l_node_list = dap_chain_net_get_node_list_cfg(l_net);
+    l_node_addr_list = dap_chain_net_get_node_list_cfg(l_net);
     for(size_t i=0;i<l_nodes_count;i++)
     {
-        for(dap_list_t *node_i = l_node_list;node_i;node_i = node_i->next)
+        bool l_check = true;
+        for(dap_list_t *node_i = l_node_addr_list;node_i;node_i = node_i->next)
         {
-            dap_chain_node_info_t *l_node_cfg = (dap_chain_node_info_t*)node_i->data;
+            struct in_addr *l_node_addr_cfg = (struct in_addr*)node_i->data;
             dap_chain_node_info_t *l_node_cand = (dap_chain_node_info_t *)l_objs[i].value;
             if(l_node_cand->hdr.ext_addr_v4.s_addr && l_node_cand->hdr.ext_port &&
-                (l_node_cfg->hdr.ext_addr_v4.s_addr != l_node_cand->hdr.ext_addr_v4.s_addr))
+                (l_node_addr_cfg->s_addr != l_node_cand->hdr.ext_addr_v4.s_addr))
             {
-                l_objs_list = dap_list_append(l_objs_list,l_objs[i].value);
-                l_node_num++;
+                continue;
+            }
+            else
+            {
+                l_check = false;
                 break;
             }
         }
+        if(l_check){
+            l_objs_list = dap_list_append(l_objs_list,l_objs[i].value);
+            l_node_num++;
+        }
     }
     dap_global_db_objs_delete(l_objs, l_nodes_count);
-    dap_list_free(l_node_list);
+    dap_list_free(l_node_addr_list);
     l_nodes_count = l_node_num;
     dap_chain_node_info_t *l_node_candidate;
     if(l_nodes_count)
@@ -96,18 +104,11 @@ dap_chain_node_info_t *s_balancer_issue_link(const char *a_net_name)
     }
     else
     {
-        dap_list_t *l_node_list = dap_chain_net_get_node_list_cfg(l_net);
-        uint16_t l_nods_cnt = dap_list_length(l_node_list);
-        if(l_node_list)
-        {
-            dap_chain_node_info_t *l_node_info = DAP_NEW_Z(dap_chain_node_info_t);
-            int i = rand() % l_nods_cnt;
-            dap_list_t *nl = l_node_list;
-            while(i--) nl = nl->next;
-            l_node_candidate = (dap_chain_node_info_t*)nl->data;
-            memcpy(l_node_info, l_node_candidate, sizeof(dap_chain_node_info_t));
-            dap_list_free(l_node_list);
-            return l_node_info;
+        dap_chain_node_info_t *l_link_node_info = dap_get_balancer_link_from_cfg(l_net);
+        if(l_link_node_info)
+        {          
+            log_it(L_DEBUG, "Network balancer issues ip from net conf - %s",inet_ntoa(l_link_node_info->hdr.ext_addr_v4));
+            return l_link_node_info;
         }
     }
     return NULL;
diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h
index 9cc386aa93..25b14cf485 100644
--- a/modules/net/include/dap_chain_net.h
+++ b/modules/net/include/dap_chain_net.h
@@ -35,8 +35,8 @@ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/lic
 #include "dap_string.h"
 #include "dap_list.h"
 #include "dap_chain_common.h"
-#include "dap_chain_node.h"
 #include "dap_chain.h"
+#include "dap_chain_node.h"
 #include "dap_chain_ledger.h"
 #include "dap_chain_net_decree.h"
 #include "dap_chain_datum_decree.h"
@@ -158,6 +158,8 @@ dap_list_t* dap_chain_net_get_link_node_list(dap_chain_net_t * l_net, bool a_is_
 dap_list_t* dap_chain_net_get_node_list(dap_chain_net_t * a_net);
 dap_list_t* dap_chain_net_get_node_list_cfg(dap_chain_net_t * a_net);
 dap_chain_node_role_t dap_chain_net_get_role(dap_chain_net_t * a_net);
+dap_chain_node_info_t *dap_get_balancer_link_from_cfg(dap_chain_net_t *a_net);
+
 
 /**
  * @brief dap_chain_net_get_gdb_group_mempool
diff --git a/modules/net/include/dap_chain_node.h b/modules/net/include/dap_chain_node.h
index 0eba403cc2..a098bdcc28 100644
--- a/modules/net/include/dap_chain_node.h
+++ b/modules/net/include/dap_chain_node.h
@@ -47,7 +47,7 @@
 #include "dap_chain_common.h"
 #include "dap_global_db.h"
 #include "dap_chain.h"
-#include "dap_chain_net.h"
+//#include "dap_chain_net.h"
 
 typedef struct dap_chain_net dap_chain_net_t;
 /**
-- 
GitLab