diff --git a/dap_chain_node.c b/dap_chain_node.c
index 24bad7a6f39a423cee8bf5a918d9a96c78085e1c..f9d334cab9ee8e456481283f4e57a418d122689b 100644
--- a/dap_chain_node.c
+++ b/dap_chain_node.c
@@ -75,7 +75,7 @@ bool dap_chain_node_check_addr(dap_chain_node_addr_t *addr, dap_chain_shard_id_t
  * len is the size of the data in the in[] buffer to encode.
  * return the number of bytes encoded, or -1 on error.
  */
-int bin2hex(char *out, const unsigned char *in, int len)
+int bin2hex0(char *out, const unsigned char *in, int len)
 {
     int ct = len;
     static char hex[] = "0123456789ABCDEF";
@@ -98,7 +98,7 @@ int bin2hex(char *out, const unsigned char *in, int len)
  * The buffers in[] and out[] can be the same to allow in-place decoding.
  * return the number of bytes encoded, or -1 on error.
  */
-int hex2bin(char *out, const unsigned char *in, int len)
+int hex2bin0(char *out, const unsigned char *in, int len)
 {
     // '0'-'9' = 0x30-0x39
     // 'a'-'f' = 0x61-0x66
@@ -131,7 +131,7 @@ size_t dap_chain_node_info_get_size(dap_chain_node_info_t *node_info)
  * size[out] - length of output string
  * return data or NULL if error
  */
-uint8_t* dap_chain_node_info_serialize(dap_chain_node_info_t *node_info, size_t *size)
+/*uint8_t* dap_chain_node_info_serialize(dap_chain_node_info_t *node_info, size_t *size)
 {
     if(!node_info)
         return NULL;
@@ -146,14 +146,14 @@ uint8_t* dap_chain_node_info_serialize(dap_chain_node_info_t *node_info, size_t
     if(size)
         *size = node_info_str_size;
     return node_info_str;
-}
+}*/
 
 /**
  * Deserialize dap_chain_node_info_t
  * size[in] - length of input string
  * return data or NULL if error
  */
-dap_chain_node_info_t* dap_chain_node_info_deserialize(uint8_t *node_info_str, size_t size)
+/*dap_chain_node_info_t* dap_chain_node_info_deserialize(uint8_t *node_info_str, size_t size)
 {
     if(!node_info_str || size<=0)
         return NULL;
@@ -166,5 +166,5 @@ dap_chain_node_info_t* dap_chain_node_info_deserialize(uint8_t *node_info_str, s
         return NULL;
     }
     return node_info;
-}
+}*/
 
diff --git a/dap_chain_node.h b/dap_chain_node.h
index 3acebe28df917068b9723fe8ffc6fbfdcfe0f1f6..787f97397b5c450f2e285e0abfad9d414998bc42 100644
--- a/dap_chain_node.h
+++ b/dap_chain_node.h
@@ -100,14 +100,14 @@ size_t dap_chain_node_info_get_size(dap_chain_node_info_t *node_info);
  * size[out] - length of output string
  * return data or NULL if error
  */
-uint8_t* dap_chain_node_info_serialize(dap_chain_node_info_t *node_info, size_t *size);
+//uint8_t* dap_chain_node_info_serialize(dap_chain_node_info_t *node_info, size_t *size);
 
 /**
  * Deserialize dap_chain_node_info_t
  * size[in] - length of input string
  * return data or NULL if error
  */
-dap_chain_node_info_t* dap_chain_node_info_deserialize(uint8_t *node_info_str, size_t size);
+//dap_chain_node_info_t* dap_chain_node_info_deserialize(uint8_t *node_info_str, size_t size);
 
 /**
  * Generate node addr by shard id
diff --git a/dap_chain_node_cli.c b/dap_chain_node_cli.c
index 4efe82a53ba64bccab20b14b706cf8657a06433f..600387ed652610ebb1f85127d8eab4739bd7f71b 100644
--- a/dap_chain_node_cli.c
+++ b/dap_chain_node_cli.c
@@ -23,7 +23,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
-#include <glib.h>
+//#include <glib.h>
 
 #ifndef _WIN32
 #include <poll.h>
@@ -48,6 +48,8 @@ typedef int SOCKET;
 
 #include "iputils/iputils.h"
 #include "dap_common.h"
+#include "dap_strfuncs.h"
+#include "dap_list.h"
 #include "dap_chain_node_cli_cmd.h"
 #include "dap_chain_node_client.h"
 #include "dap_chain_node_cli.h"
@@ -265,7 +267,7 @@ static void* thread_one_client_func(void *args)
     int timeout = 5000; // 5 sec
     char **argv = NULL;
     int argc = 0;
-    GList *cmd_param_list = NULL;
+    dap_list_t *cmd_param_list = NULL;
     while(1)
     {
         // wait data from client
@@ -294,57 +296,57 @@ static void* thread_one_client_func(void *args)
         }
         // filling parameters of command
         if(marker == 1) {
-            cmd_param_list = g_list_append(cmd_param_list, str_header);
+            cmd_param_list = dap_list_append(cmd_param_list, str_header);
             //printf("g_list_append argc=%d command=%s ", argc, str_header);
             argc++;
         }
         else
             free(str_header);
         if(marker == 2) {
-            GList *list = cmd_param_list;
+            dap_list_t *list = cmd_param_list;
             // form command
-            guint argc = g_list_length(list);
+            unsigned int argc = dap_list_length(list);
             // command is found
             if(argc >= 1) {
                 char *cmd_name = list->data;
-                list = g_list_next(list);
+                list = dap_list_next(list);
                 // execute command
-                char *str_cmd = g_strdup_printf("%s", cmd_name);
+                char *str_cmd = dap_strdup_printf("%s", cmd_name);
                 const COMMAND *command = find_command(cmd_name);
                 int res = -1;
                 char *str_reply = NULL;
                 if(command)
                 {
                     while(list) {
-                        str_cmd = g_strdup_printf("%s;%s", str_cmd, list->data);
-                        list = g_list_next(list);
+                        str_cmd = dap_strdup_printf("%s;%s", str_cmd, list->data);
+                        list = dap_list_next(list);
                     }
                     log_it(L_INFO, "execute command=%s", str_cmd);
                     // exec command
 
-                    char **argv = g_strsplit(str_cmd, ";", -1);
+                    char **argv = dap_strsplit(str_cmd, ";", -1);
                     // Call the command function
                     if(command && command->func)
                         res = (*(command->func))(argc, (const char **) argv, &str_reply);
-                    g_strfreev(argv);
+                    dap_strfreev(argv);
                 }
                 else
                 {
-                    str_reply = g_strdup_printf("can't recognize command=%s", str_cmd);
+                    str_reply = dap_strdup_printf("can't recognize command=%s", str_cmd);
                     log_it(L_ERROR, str_reply);
                 }
-                gchar *reply_body = g_strdup_printf("%d\r\n%s\r\n", res, (str_reply) ? str_reply : "");
+                char *reply_body = dap_strdup_printf("%d\r\n%s\r\n", res, (str_reply) ? str_reply : "");
                 // return the result of the command function
-                gchar *reply_str = g_strdup_printf("HTTP/1.1 200 OK\r\nContent-Length: %d\r\n\r\n%s",
+                char *reply_str = dap_strdup_printf("HTTP/1.1 200 OK\r\nContent-Length: %d\r\n\r\n%s",
                         strlen(reply_body), reply_body);
-                int ret = send(newsockfd, reply_str, strlen(reply_str), 1000);
-                g_free(str_reply);
-                g_free(reply_str);
-                g_free(reply_body);
+                int ret = send(newsockfd, reply_str, strlen(reply_str) + 1, 1000);
+                DAP_DELETE(str_reply);
+                DAP_DELETE(reply_str);
+                DAP_DELETE(reply_body);
 
-                g_free(str_cmd);
+                DAP_DELETE(str_cmd);
             }
-            g_list_free_full(cmd_param_list, free);
+            dap_list_free_full(cmd_param_list, free);
             break;
         }
     }
diff --git a/dap_chain_node_cli_cmd.c b/dap_chain_node_cli_cmd.c
index 2ddfdd6d2ee82167747a9b28c0d020a54c53b779..cd75919f2acc6b24adf3a23fd29d728f09bcca2f 100644
--- a/dap_chain_node_cli_cmd.c
+++ b/dap_chain_node_cli_cmd.c
@@ -31,9 +31,12 @@
 #include <netinet/in.h>
 
 #include "iputils/iputils.h"
-//#include "dap_common.h"
+#include "dap_string.h"
 #include "dap_hash.h"
 #include "dap_chain_common.h"
+#include "dap_strfuncs.h"
+#include "dap_list.h"
+#include "dap_string.h"
 #include "dap_chain_wallet.h"
 #include "dap_chain_node.h"
 #include "dap_chain_global_db.h"
@@ -45,13 +48,11 @@
 #include "dap_chain_datum_tx_ctrl.h"
 #include "dap_chain_datum_tx_items.h"
 #include "dap_chain_datum_tx_cache.h"
+#include "dap_chain_global_db.h"
+#include "dap_chain_global_db_remote.h"
 
 #include "dap_stream_ch_chain_net.h"
 
-// Max and min macros
-#define max(a,b)              ((a) > (b) ? (a) : (b))
-#define min(a,b)              ((a) < (b) ? (a) : (b))
-
 #define LOG_TAG "chain_node_cli_cmd"
 
 /**
@@ -112,11 +113,11 @@ static void digit_from_string(const char *num_str, uint8_t *raw, size_t raw_len)
 static bool add_alias(const char *alias, dap_chain_node_addr_t *addr)
 {
     const char *a_key = alias;
-    char a_value[2 * sizeof(dap_chain_node_addr_t) + 1];
-    if(bin2hex(a_value, (const unsigned char *) addr, sizeof(dap_chain_node_addr_t)) == -1)
-        return false;
-    a_value[2 * sizeof(dap_chain_node_addr_t)] = '\0';
-    bool res = dap_chain_global_db_gr_set(a_key, a_value, GROUP_ALIAS);
+//    char a_value[2 * sizeof(dap_chain_node_addr_t) + 1];
+//    if(bin2hex(a_value, (const unsigned char *) addr, sizeof(dap_chain_node_addr_t)) == -1)
+//        return false;
+//    a_value[2 * sizeof(dap_chain_node_addr_t)] = '\0';
+    bool res = dap_chain_global_db_gr_set(a_key, (const uint8_t*) addr, sizeof(dap_chain_node_addr_t), GROUP_ALIAS);
     return res;
 }
 
@@ -135,22 +136,23 @@ static bool del_alias(const char *alias)
  *
  * return addr, NULL if not found
  */
-dap_chain_node_addr_t* get_name_by_alias(const char *alias)
+dap_chain_node_addr_t* get_name_by_alias(const char *a_alias)
 {
-    dap_chain_node_addr_t *addr = NULL;
-    if(!alias)
+    dap_chain_node_addr_t *l_addr = NULL;
+    if(!a_alias)
         return NULL;
-    const char *a_key = alias;
-    char *addr_str = dap_chain_global_db_gr_get(a_key, GROUP_ALIAS);
-    if(addr_str && strlen(addr_str) == sizeof(dap_chain_node_addr_t) * 2) {
-        addr = DAP_NEW_Z(dap_chain_node_addr_t);
-        if(hex2bin((char*) addr, (const unsigned char *) addr_str, sizeof(dap_chain_node_addr_t) * 2) == -1) {
-            DAP_DELETE(addr);
-            addr = NULL;
-        }
-    }
-    DAP_DELETE(addr_str);
-    return addr;
+    const char *a_key = a_alias;
+    size_t l_addr_out = 0;
+    l_addr = (dap_chain_node_addr_t*) dap_chain_global_db_gr_get(a_key, &l_addr_out, GROUP_ALIAS);
+    if(l_addr_out != sizeof(dap_chain_node_addr_t)) {
+//        l_addr = DAP_NEW_Z(dap_chain_node_addr_t);
+//        if(hex2bin((char*) l_addr, (const unsigned char *) addr_str, sizeof(dap_chain_node_addr_t) * 2) == -1) {
+        DAP_DELETE(l_addr);
+//            l_addr = NULL;
+//        }
+    }
+//    DAP_DELETE(addr_str);
+    return l_addr;
 }
 
 /**
@@ -158,14 +160,14 @@ dap_chain_node_addr_t* get_name_by_alias(const char *alias)
  *
  * return list of addr, NULL if not found
  */
-static GList* get_aliases_by_name(dap_chain_node_addr_t *addr)
+static dap_list_t* get_aliases_by_name(dap_chain_node_addr_t *a_addr)
 {
-    if(!addr)
+    if(!a_addr)
         return NULL;
-    GList *list_aliases = NULL;
+    dap_list_t *list_aliases = NULL;
     size_t data_size = 0;
     // read all aliases
-    dap_global_db_obj_t **objs = dap_chain_global_db_gr_load(&data_size, GROUP_ALIAS);
+    dap_global_db_obj_t **objs = dap_chain_global_db_gr_load(GROUP_ALIAS, &data_size);
     if(!objs || !data_size)
         return NULL;
     for(int i = 0; i < data_size; i++) {
@@ -173,16 +175,20 @@ static GList* get_aliases_by_name(dap_chain_node_addr_t *addr)
         dap_global_db_obj_t *obj = objs[i];
         if(!obj)
             break;
-        char *addr_str = obj->value;
-        if(addr_str && strlen(addr_str) == sizeof(dap_chain_node_addr_t) * 2) {
-            //addr_i = DAP_NEW_Z(dap_chain_node_addr_t);
-            if(hex2bin((char*) &addr_i, (const unsigned char *) addr_str, sizeof(dap_chain_node_addr_t) * 2) == -1) {
-                continue;
-            }
-            if(addr->uint64 == addr_i.uint64) {
-                list_aliases = g_list_prepend(list_aliases, strdup(obj->key));
-            }
+        dap_chain_node_addr_t *l_addr = (dap_chain_node_addr_t*) obj->value;
+        if(l_addr && obj->value_len == sizeof(dap_chain_node_addr_t) && a_addr->uint64 == l_addr->uint64) {
+            list_aliases = dap_list_prepend(list_aliases, strdup(obj->key));
         }
+        /*        char *addr_str = obj->value;
+         if(addr_str && strlen(addr_str) == sizeof(dap_chain_node_addr_t) * 2) {
+         //addr_i = DAP_NEW_Z(dap_chain_node_addr_t);
+         if(hex2bin((char*) &addr_i, (const unsigned char *) addr_str, sizeof(dap_chain_node_addr_t) * 2) == -1) {
+         continue;
+         }
+         if(a_addr->uint64 == addr_i.uint64) {
+         list_aliases = dap_list_prepend(list_aliases, strdup(obj->key));
+         }
+         }*/
     }
     dap_chain_global_db_objs_delete(objs);
     return list_aliases;
@@ -216,12 +222,12 @@ static void set_reply_text(char **str_reply, const char *str, ...)
     if(str_reply) {
         if(*str_reply) {
             assert(!*str_reply);
-            g_free(*str_reply);
+            DAP_DELETE(*str_reply);
             *str_reply = NULL;
         }
         va_list args;
         va_start(args, str);
-        *str_reply = g_strdup_vprintf(str, args); //*str_reply = g_strdup(str);
+        *str_reply = dap_strdup_vprintf(str, args); //*str_reply = dap_strdup(str);
         va_end(args);
     }
 }
@@ -231,30 +237,41 @@ static void set_reply_text(char **str_reply, const char *str, ...)
  */
 static dap_chain_node_info_t* dap_chain_node_info_read(dap_chain_node_addr_t *address, char **str_reply)
 {
-    char *a_key = com_global_db_get_key_for_addr(address);
-    if(!a_key)
+    char *l_key = com_global_db_get_key_for_addr(address);
+    if(!l_key)
     {
         set_reply_text(str_reply, "can't calculate hash of addr");
         return NULL;
     }
+    size_t node_info_size = 0;
+    dap_chain_node_info_t *node_info;
     // read node
-    char *str = dap_chain_global_db_gr_get(a_key, GROUP_NODE);
-    if(!str) {
+    node_info = (dap_chain_node_info_t *) dap_chain_global_db_gr_get(l_key, &node_info_size, GROUP_NODE);
+
+    if(!node_info) {
         set_reply_text(str_reply, "node not found in base");
-        DAP_DELETE(a_key);
+        DAP_DELETE(l_key);
         return NULL;
     }
-    dap_chain_node_info_t *node_info = dap_chain_node_info_deserialize(str, (str) ? strlen(str) : 0);
-    if(!node_info) {
-        set_reply_text(str_reply, "node has invalid format in base");
+    size_t node_info_size_must_be = dap_chain_node_info_get_size(node_info);
+    if(node_info_size_must_be != node_info_size) {
+        set_reply_text(str_reply, "node has bad size in base=%u (must be %u)", node_info_size, node_info_size_must_be);
+        DAP_DELETE(node_info);
+        DAP_DELETE(l_key);
+        return NULL;
     }
-    DAP_DELETE(str);
-    DAP_DELETE(a_key);
+
+//    dap_chain_node_info_t *node_info = dap_chain_node_info_deserialize(str, (str) ? strlen(str) : 0);
+//    if(!node_info) {
+//        set_reply_text(str_reply, "node has invalid format in base");
+//    }
+//    DAP_DELETE(str);
+    DAP_DELETE(l_key);
     return node_info;
 }
 
 /**
- * Save node from base
+ * Save node to base
  */
 static bool dap_chain_node_info_save(dap_chain_node_info_t *node_info, char **str_reply)
 {
@@ -268,10 +285,11 @@ static bool dap_chain_node_info_save(dap_chain_node_info_t *node_info, char **st
         set_reply_text(str_reply, "can't calculate hash for addr");
         return NULL;
     }
-    char *a_value = dap_chain_node_info_serialize(node_info, NULL);
-    bool res = dap_chain_global_db_gr_set(a_key, a_value, GROUP_NODE);
+    //char *a_value = dap_chain_node_info_serialize(node_info, NULL);
+    size_t node_info_size = dap_chain_node_info_get_size(node_info);
+    bool res = dap_chain_global_db_gr_set(a_key, (const uint8_t *) node_info, node_info_size, GROUP_NODE);
     DAP_DELETE(a_key);
-    DAP_DELETE(a_value);
+    //DAP_DELETE(a_value);
     return res;
 }
 /**
@@ -341,6 +359,13 @@ static int com_global_db_del(dap_chain_node_info_t *node_info, const char *alias
         set_reply_text(str_reply, "addr not found");
         return -1;
     }
+    // check, current node have this addr or no
+    uint64_t l_cur_addr = dap_db_get_cur_node_addr();
+    if(l_cur_addr && l_cur_addr == node_info->hdr.address.uint64) {
+        set_reply_text(str_reply, "current node cannot be deleted");
+        return -1;
+    }
+
     // find addr by alias or addr_str
     dap_chain_node_addr_t *address = com_global_db_get_addr(node_info, &node_info->hdr.address, alias_str);
     if(!address) {
@@ -355,15 +380,15 @@ static int com_global_db_del(dap_chain_node_info_t *node_info, const char *alias
         if(res) {
             // delete all aliases for node address
             {
-                GList *list_aliases = get_aliases_by_name(address);
-                GList *list = list_aliases;
+                dap_list_t *list_aliases = get_aliases_by_name(address);
+                dap_list_t *list = list_aliases;
                 while(list)
                 {
                     const char *alias = (const char *) list->data;
                     del_alias(alias);
-                    list = g_list_next(list);
+                    list = dap_list_next(list);
                 }
-                g_list_free_full(list_aliases, (GDestroyNotify) free);
+                dap_list_free_full(list_aliases, (DapDestroyNotify) free);
             }
             // set text response
             set_reply_text(str_reply, "node deleted");
@@ -492,70 +517,253 @@ static int com_global_db_link(dap_chain_node_info_t *node_info, const char *cmd,
  * str_reply[out] for reply
  * return 0 Ok, -1 error
  */
-static int com_global_db_dump(dap_chain_node_info_t *node_info, const char *alias_str, char **str_reply)
+static int com_global_db_dump(dap_chain_node_info_t *a_node_info, const char *alias_str, char **str_reply)
 {
-    char *a_key = NULL;
-    if(!node_info->hdr.address.uint64 && !alias_str) {
-        set_reply_text(str_reply, "addr not found");
+    size_t l_nodes_count = 1;
+    //bool show_all_addr = false;
+    dap_global_db_obj_t **l_objs = NULL;
+    if(!a_node_info->hdr.address.uint64 && !alias_str) {
+        //set_reply_text(str_reply, "addr not found");
+        //return -1;
+        //show_all_addr = true;
+        // read all nodes
+        dap_chain_node_info_t *node_info;
+        // read all node
+        l_objs = dap_chain_global_db_gr_load(GROUP_NODE, &l_nodes_count);
+        /*for(size_t i = 0; i < l_nodes_count; i++) {
+         dap_global_db_obj_t *l_obj = l_objs[i];
+         dap_chain_node_info_t *node_info = (dap_chain_node_info_t *) l_obj->value;
+         node_info->
+
+         }*/
+        if(!l_nodes_count || !l_objs) {
+            set_reply_text(str_reply, "nodes not found");
+            return -1;
+        }
+    }
+    size_t i;
+    dap_string_t *l_string_reply = dap_string_new(NULL);
+    for(i = 0; i < l_nodes_count; i++) {
+        dap_chain_node_info_t *node_info = (!l_objs) ? a_node_info : (dap_chain_node_info_t *) l_objs[i]->value;
+        // find addr by alias or addr_str
+        dap_chain_node_addr_t *address = com_global_db_get_addr(node_info, &node_info->hdr.address, alias_str);
+        if(!address) {
+            set_reply_text(str_reply, "alias not found");
+            break;
+        }
+        // read node
+        dap_chain_node_info_t *node_info_read = dap_chain_node_info_read(address, str_reply);
+        if(!node_info_read) {
+            DAP_DELETE(address);
+            break;
+        }
+
+        int hostlen = 128;
+        char host4[hostlen];
+        char host6[hostlen];
+        struct sockaddr_in sa4 = { .sin_family = AF_INET, .sin_addr = node_info_read->hdr.ext_addr_v4 };
+        const char* str_ip4 = inet_ntop(AF_INET, &(((struct sockaddr_in *) &sa4)->sin_addr), host4, hostlen);
+
+        struct sockaddr_in6 sa6 = { .sin6_family = AF_INET6, .sin6_addr = node_info_read->hdr.ext_addr_v6 };
+        const char* str_ip6 = inet_ntop(AF_INET6, &(((struct sockaddr_in6 *) &sa6)->sin6_addr), host6, hostlen);
+
+        // get aliases in form of string
+        dap_string_t *aliases_string = dap_string_new(NULL);
+        dap_list_t *list_aliases = get_aliases_by_name(address);
+        if(list_aliases)
+        {
+            dap_list_t *list = list_aliases;
+            while(list)
+            {
+                const char *alias = (const char *) list->data;
+                dap_string_append_printf(aliases_string, "\nalias %s", alias);
+                list = dap_list_next(list);
+            }
+            dap_list_free_full(list_aliases, (DapDestroyNotify) free);
+        }
+        else
+            dap_string_append(aliases_string, "\nno aliases");
+
+        // get links in form of string
+        dap_string_t *links_string = dap_string_new(NULL);
+        for(int i = 0; i < node_info_read->hdr.links_number; i++) {
+            dap_chain_node_addr_t link_addr = node_info_read->links[i];
+            dap_string_append_printf(links_string, "\nlink%02d address : 0x%llx", i, link_addr.uint64);
+        }
+
+        if(i)
+            dap_string_append_printf(l_string_reply, "\n");
+        // set short reply with node param
+        if(l_objs)
+            dap_string_append_printf(l_string_reply,
+                    "node address 0x%llx\tshard 0x%llx\tipv4 %s\tnumber of links %d",
+                    node_info_read->hdr.address, node_info_read->hdr.shard_id,
+                    str_ip4, node_info_read->hdr.links_number);
+        else
+            // set full reply with node param
+            dap_string_append_printf(l_string_reply,
+                    "node address 0x%llx\nshard 0x%llx%s\nipv4 %s\nipv6 %s\nlinks %d%s",
+                    node_info_read->hdr.address, node_info_read->hdr.shard_id, aliases_string->str,
+                    str_ip4, str_ip6,
+                    node_info_read->hdr.links_number, links_string->str);
+        dap_string_free(aliases_string, true);
+        dap_string_free(links_string, true);
+
+        DAP_DELETE(address);
+        DAP_DELETE(node_info_read);
+    }
+    if(i == l_nodes_count) {
+        // set full reply with node param
+        set_reply_text(str_reply, l_string_reply->str);
+    }
+    dap_string_free(l_string_reply, true);
+    if(i < l_nodes_count)
+        return -1;
+    else
+        return 0;
+}
+
+/**
+ * Handler of command 'global_db node get'
+ *
+ * str_reply[out] for reply
+ * return 0 Ok, -1 error
+ */
+static int com_global_db_get(char **a_str_reply)
+{
+    // get cur node addr
+    uint64_t l_addr = dap_db_get_cur_node_addr();
+    if(l_addr) {
+        set_reply_text(a_str_reply, "address for current node is 0x%llu", l_addr);
+        return 0;
+    }
+    set_reply_text(a_str_reply, "address for node has not been set.");
+    return -1;
+}
+
+/**
+ * Handler of command 'global_db node set'
+ *
+ * str_reply[out] for reply
+ * return 0 Ok, -1 error
+ */
+static int com_global_db_set(dap_chain_node_info_t *a_node_info, const char *a_alias_str, char **a_str_reply)
+{
+    if(!a_node_info->hdr.address.uint64 && !a_alias_str) {
+        set_reply_text(a_str_reply, "addr not found");
         return -1;
     }
     // find addr by alias or addr_str
-    dap_chain_node_addr_t *address = com_global_db_get_addr(node_info, &node_info->hdr.address, alias_str);
-    if(!address) {
-        set_reply_text(str_reply, "alias not found");
+    dap_chain_node_addr_t *l_address = com_global_db_get_addr(a_node_info, &a_node_info->hdr.address, a_alias_str);
+    if(!l_address) {
+        set_reply_text(a_str_reply, "alias not found");
         return -1;
     }
     // read node
-    dap_chain_node_info_t *node_info_read = dap_chain_node_info_read(address, str_reply);
-    if(!node_info_read) {
-        DAP_DELETE(address);
+    dap_chain_node_info_t *l_node_info_read = dap_chain_node_info_read(l_address, a_str_reply);
+    if(!l_node_info_read) {
+        DAP_DELETE(l_address);
         return -1;
     }
+    // set cur node addr
+    if(dap_db_set_cur_node_addr(l_node_info_read->hdr.address.uint64)) {
+        set_reply_text(a_str_reply, "new address for node has been set");
+        return 0;
+    }
+    set_reply_text(a_str_reply, "new address for node has not been set");
+    return -1;
+}
 
-    int hostlen = 128;
-    char host4[hostlen];
-    char host6[hostlen];
-    struct sockaddr_in sa4 = { .sin_family = AF_INET, .sin_addr = node_info_read->hdr.ext_addr_v4 };
-    const char* str_ip4 = inet_ntop(AF_INET, &(((struct sockaddr_in *) &sa4)->sin_addr), host4, hostlen);
-
-    struct sockaddr_in6 sa6 = { .sin6_family = AF_INET6, .sin6_addr = node_info_read->hdr.ext_addr_v6 };
-    const char* str_ip6 = inet_ntop(AF_INET6, &(((struct sockaddr_in6 *) &sa6)->sin6_addr), host6, hostlen);
-
-    // get aliases in form of string
-    GString *aliases_string = g_string_new(NULL);
-    GList *list_aliases = get_aliases_by_name(address);
-    if(list_aliases)
-    {
-        GList *list = list_aliases;
-        while(list)
-        {
-            const char *alias = (const char *) list->data;
-            g_string_append_printf(aliases_string, "\nalias %s", alias);
-            list = g_list_next(list);
-        }
-        g_list_free_full(list_aliases, (GDestroyNotify) free);
+/**
+ * Handler of command 'global_db node remote_set'
+ *
+ * str_reply[out] for reply
+ * return 0 Ok, -1 error
+ */
+static int com_global_db_set_remote(dap_chain_node_info_t *a_node_info, const char *a_alias_str, char **a_str_reply)
+{
+    if(!a_node_info->hdr.address.uint64 && !a_alias_str) {
+        set_reply_text(a_str_reply, "addr not found");
+        return -1;
+    }
+    // find addr by alias or addr_str
+    dap_chain_node_addr_t *l_address = com_global_db_get_addr(a_node_info, &a_node_info->hdr.address, a_alias_str);
+    if(!l_address) {
+        set_reply_text(a_str_reply, "alias not found");
+        return -1;
+    }
+    // read node
+    dap_chain_node_info_t *l_node_info_read = dap_chain_node_info_read(l_address, a_str_reply);
+    if(!l_node_info_read) {
+        DAP_DELETE(l_address);
+        return -1;
     }
-    else
-        g_string_append(aliases_string, "\nno aliases");
 
-    // get links in form of string
-    GString *links_string = g_string_new(NULL);
-    for(int i = 0; i < node_info_read->hdr.links_number; i++) {
-        dap_chain_node_addr_t link_addr = node_info_read->links[i];
-        g_string_append_printf(links_string, "\nlink%02d address : 0x%llx", i, link_addr.uint64);
+    // get cur node addr
+    uint64_t l_cur_node_addr = dap_db_get_cur_node_addr(); //0x12345
+    if(!l_cur_node_addr) {
+        set_reply_text(a_str_reply, "current node has no address");
+        return -1;
+    }
+    dap_chain_node_info_t *l_node_info = dap_chain_node_info_read(l_address, a_str_reply);
+    if(!l_node_info) {
+        return -1;
+    }
+    // start connect
+    dap_chain_node_client_t *client = dap_chain_node_client_connect(l_node_info);
+    if(!client) {
+        set_reply_text(a_str_reply, "can't connect");
+        DAP_DELETE(l_node_info);
+        return -1;
+    }
+    // wait connected
+    int timeout_ms = 150000; //15 sec = 15000 ms
+    int res = chain_node_client_wait(client, NODE_CLIENT_STATE_CONNECTED, timeout_ms);
+    if(res != 1) {
+        set_reply_text(a_str_reply, "no response from node");
+        // clean client struct
+        dap_chain_node_client_close(client);
+        DAP_DELETE(l_node_info);
+        return -1;
     }
 
-    // set full reply with node param
-    set_reply_text(str_reply, "node address 0x%llx\nshard 0x%llx%s\nipv4 %s\nipv6 %s\nnumber of links %d%s",
-            node_info_read->hdr.address, node_info_read->hdr.shard_id, aliases_string->str,
-            str_ip4, str_ip6,
-            node_info_read->hdr.links_number, links_string->str);
-    g_string_free(aliases_string, TRUE);
-    g_string_free(links_string, TRUE);
+    // send request
+    res = dap_chain_node_client_send_chain_net_request(client, dap_stream_ch_chain_net_get_id(),
+    STREAM_CH_CHAIN_NET_PKT_TYPE_SET_NODE_ADDR, (char*)&l_node_info->hdr.address.uint64, sizeof(uint64_t)); //, NULL);
+    if(res != 1) {
+        set_reply_text(a_str_reply, "no request sent");
+        // clean client struct
+        dap_chain_node_client_close(client);
+        DAP_DELETE(l_node_info);
+        return -1;
+    }
 
-    DAP_DELETE(address);
-    DAP_DELETE(node_info_read);
+    // wait for finishing of request
+    timeout_ms = 9120000; // 2 min = 120 sec = 120 000 ms
+    res = chain_node_client_wait(client, NODE_CLIENT_STATE_GET_NODE_ADDR, timeout_ms);
+    DAP_DELETE(l_node_info);
+    dap_client_disconnect(client->client);
+    dap_chain_node_client_close(client);
+    switch (res) {
+    case 0:
+        set_reply_text(a_str_reply, "timeout");
+        return -1;
+    case 1: {
+        uint64_t addr = 0;
+        if(client->recv_data_len == sizeof(uint64_t))
+            memcpy(&addr, client->recv_data, sizeof(uint64_t));
+        if(client->recv_data_len > 0)
+            DAP_DELETE(client->recv_data);
+        client->recv_data = NULL;
+        set_reply_text(a_str_reply, "new address for remote node has been set 0x%x", addr);
+    }
+        return 0;
+    default:
+        set_reply_text(a_str_reply, "error");
+        return -1;
+    }
 
+    set_reply_text(a_str_reply, "not implement");
     return -1;
 }
 
@@ -567,13 +775,13 @@ static int com_global_db_dump(dap_chain_node_info_t *node_info, const char *alia
 int com_global_db(int argc, const char ** argv, char **str_reply)
 {
     enum {
-        CMD_NONE, CMD_ADD, CMD_DEL, CMD_LINK, CMD_DUMP
+        CMD_NONE, CMD_ADD, CMD_DEL, CMD_LINK, CMD_DUMP, CMD_GET, CMD_SET, CMD_REMOTE_SET
     };
-    printf("com_global_db\n");
+    //printf("com_global_db\n");
     int arg_index = 1;
     // find 'node' as first parameter only
     arg_index = find_option_val(argv, arg_index, min(argc, arg_index + 1), "node", NULL);
-    if(!arg_index || argc < 4) {
+    if(!arg_index || argc < 3) {
         set_reply_text(str_reply, "parameters are not valid");
         return -1;
     }
@@ -592,6 +800,15 @@ int com_global_db(int argc, const char ** argv, char **str_reply)
     else if((arg_index_n = find_option_val(argv, arg_index, min(argc, arg_index + 1), "dump", NULL)) != 0) {
         cmd_num = CMD_DUMP;
     }
+    else if((arg_index_n = find_option_val(argv, arg_index, min(argc, arg_index + 1), "get", NULL)) != 0) {
+        cmd_num = CMD_GET;
+    }
+    else if((arg_index_n = find_option_val(argv, arg_index, min(argc, arg_index + 1), "set", NULL)) != 0) {
+        cmd_num = CMD_SET;
+    }
+    else if((arg_index_n = find_option_val(argv, arg_index, min(argc, arg_index + 1), "remote_set", NULL)) != 0) {
+        cmd_num = CMD_REMOTE_SET;
+    }
     if(cmd_num == CMD_NONE) {
         set_reply_text(str_reply, "command %s not recognized", argv[1]);
         return -1;
@@ -657,6 +874,19 @@ int com_global_db(int argc, const char ** argv, char **str_reply)
         // handler of command 'global_db node dump'
         return com_global_db_dump(&node_info, alias_str, str_reply);
         break;
+    case CMD_GET:
+        // handler of command 'global_db node get'
+        return com_global_db_get(str_reply);
+        break;
+    case CMD_SET:
+        // handler of command 'global_db node set'
+        return com_global_db_set(&node_info, alias_str, str_reply);
+        break;
+    case CMD_REMOTE_SET:
+        // handler of command 'global_db node remote_set'
+        return com_global_db_set_remote(&node_info, alias_str, str_reply);
+        break;
+
     default:
         set_reply_text(str_reply, "command %s not recognized", argv[1]);
         return -1;
@@ -742,12 +972,41 @@ int com_node(int argc, const char ** argv, char **str_reply)
             return -1;
         }
 
+        // get cur node addr
+        uint64_t l_cur_node_addr = dap_db_get_cur_node_addr(); //0x12345
+        if(!l_cur_node_addr) {
+            set_reply_text(str_reply, "node has no address");
+            return -1;
+        }
+
+        /*// debug
+         //if(0)
+         {
+         #include "dap_chain_global_db.h"
+         size_t l_data_size_out = 0;
+         dap_global_db_obj_t a_objs[2];
+         a_objs[0].key = "k1";
+         a_objs[1].key = "k2";
+         a_objs[0].value = "v1";
+         a_objs[0].value_len = strlen(a_objs[0].value);
+         a_objs[1].value = "v2";
+         a_objs[1].value_len = strlen(a_objs[1].value);
+         dap_chain_global_db_save(a_objs, 2); //dap_chain_global_db_save
+         char *l_diff = dap_db_log_get_diff(NULL);
+         DAP_DELETE(l_diff);
+         dap_global_db_obj_t **db1 = dap_chain_global_db_gr_load(GROUP_DATUM, &l_data_size_out);
+         printf("GROUP_DATUM size = %d\n", l_data_size_out);
+         dap_global_db_obj_t **db2 = dap_chain_global_db_gr_load(GROUP_ALIAS, &l_data_size_out);
+         printf("GROUP_ALIAS size = %d\n", l_data_size_out);
+         dap_global_db_obj_t **db3 = dap_chain_global_db_gr_load(GROUP_NODE, &l_data_size_out);
+         printf("GROUP_NODE size = %d\n", l_data_size_out);
+         //set_reply_text(str_reply, "debug ok");
+         //return 0;
+         }*/
         dap_chain_node_info_t *node_info = dap_chain_node_info_read(&address, str_reply);
         if(!node_info) {
-            set_reply_text(str_reply, "node by addr not found");
             return -1;
         }
-        int timeout_ms = 1000000; //10 sec = 10000 ms
         // start connect
         dap_chain_node_client_t *client = dap_chain_node_client_connect(node_info);
         if(!client) {
@@ -756,6 +1015,7 @@ int com_node(int argc, const char ** argv, char **str_reply)
             return -1;
         }
         // wait connected
+        int timeout_ms = 150000; //15 sec = 15000 ms
         int res = chain_node_client_wait(client, NODE_CLIENT_STATE_CONNECTED, timeout_ms);
         if(res != 1) {
             set_reply_text(str_reply, "no response from node");
@@ -766,10 +1026,19 @@ int com_node(int argc, const char ** argv, char **str_reply)
         }
 
         // send request
+        size_t l_data_size_out = 0;
+        // Get last timestamp in log
+        time_t l_timestamp_start = dap_db_log_get_last_timestamp();
+        size_t l_data_send_len = 0;
+        uint8_t *l_data_send = dap_stream_ch_chain_net_make_packet(l_cur_node_addr, node_info->hdr.address.uint64,
+                l_timestamp_start, NULL, 0, &l_data_send_len);
+
         uint8_t l_ch_id = dap_stream_ch_chain_net_get_id(); // Channel id for global_db sync
-        res = dap_chain_node_client_send_chain_request(client, l_ch_id, "start", 5); //, NULL);
+        res = dap_chain_node_client_send_chain_net_request(client, l_ch_id,
+        STREAM_CH_CHAIN_NET_PKT_TYPE_GLOBAL_DB_REQUEST_SYNC, l_data_send, l_data_send_len); //, NULL);
+        DAP_DELETE(l_data_send);
         if(res != 1) {
-            set_reply_text(str_reply, "no response from node(send request)");
+            set_reply_text(str_reply, "no request sent");
             // clean client struct
             dap_chain_node_client_close(client);
             DAP_DELETE(node_info);
@@ -777,12 +1046,24 @@ int com_node(int argc, const char ** argv, char **str_reply)
         }
 
         // wait for finishing of request
-        res = chain_node_client_wait(client, NODE_CLIENT_STATE_PONG, timeout_ms);
+        timeout_ms = 9120000; // 2 min = 120 sec = 120 000 ms
+        // TODO add progress info to console
+        res = chain_node_client_wait(client, NODE_CLIENT_STATE_END, timeout_ms);
         DAP_DELETE(node_info);
         dap_client_disconnect(client->client);
         dap_chain_node_client_close(client);
+        switch (res) {
+        case 0:
+            set_reply_text(str_reply, "timeout");
+            return -1;
+        case 1:
+            set_reply_text(str_reply, "nodes sync completed");
+            return 0;
+        default:
+            set_reply_text(str_reply, "error");
+            return -1;
+        }
 
-        set_reply_text(str_reply, "getting pong");
     }
         break;
         // make handshake
@@ -805,10 +1086,8 @@ int com_node(int argc, const char ** argv, char **str_reply)
         }
 
         dap_chain_node_info_t *node_info = dap_chain_node_info_read(&address, str_reply);
-        if(!node_info) {
-            set_reply_text(str_reply, "node by addr not found");
+        if(!node_info)
             return -1;
-        }
         int timeout_ms = 10000; //10 sec = 10000 ms
         // start handshake
         dap_chain_node_client_t *client = dap_chain_node_client_connect(node_info);
@@ -1096,7 +1375,7 @@ int com_tx_wallet(int argc, const char ** argv, char **str_reply)
     find_option_val(argv, arg_index, argc, "-addr", &addr_str);
     find_option_val(argv, arg_index, argc, "-w", &wallet_name);
 
-    GString *l_string_ret = g_string_new(NULL);
+    dap_string_t *l_string_ret = dap_string_new(NULL);
     switch (cmd_num) {
     // wallet list
     case CMD_WALLET_LIST: {
@@ -1107,17 +1386,17 @@ int com_tx_wallet(int argc, const char ** argv, char **str_reply)
                 l_file = g_dir_read_name(l_dir);
                 int l_file_len = (l_file) ? strlen(l_file) : 0;
                 if(l_file_len > 8 && !g_strcmp0(l_file + l_file_len - 8, ".dwallet")) {
-                    char *l_file_path_tmp = g_strdup_printf("%s/%s", c_wallets_path, l_file);
+                    char *l_file_path_tmp = dap_strdup_printf("%s/%s", c_wallets_path, l_file);
                     dap_chain_wallet_t *l_wallet = dap_chain_wallet_open_file(l_file_path_tmp);
                     if(l_wallet) {
                         dap_chain_addr_t *l_addr = (dap_chain_addr_t *) dap_chain_wallet_get_addr(l_wallet);
                         char *l_addr_str = dap_chain_addr_to_str((dap_chain_addr_t*) l_addr);
-                        g_string_append_printf(l_string_ret, "\nwallet: %s\n", l_wallet->name);
-                        g_string_append_printf(l_string_ret, "addr: %s\n", (l_addr_str) ? l_addr_str : "-");
+                        dap_string_append_printf(l_string_ret, "\nwallet: %s\n", l_wallet->name);
+                        dap_string_append_printf(l_string_ret, "addr: %s\n", (l_addr_str) ? l_addr_str : "-");
                         DAP_DELETE(l_addr_str);
                         dap_chain_wallet_close(l_wallet);
                     }
-                    g_free(l_file_path_tmp);
+                    DAP_DELETE(l_file_path_tmp);
                 }
             }
             while(l_file);
@@ -1135,14 +1414,14 @@ int com_tx_wallet(int argc, const char ** argv, char **str_reply)
             dap_chain_addr_t *l_addr = (dap_chain_addr_t *) dap_chain_wallet_get_addr(l_wallet);
             char *l_addr_str = dap_chain_addr_to_str((dap_chain_addr_t*) l_addr);
             uint64_t balance = dap_chain_datum_tx_cache_calc_balance(l_addr);
-            g_string_append_printf(l_string_ret, "\nwallet: %s\n", l_wallet->name);
-            g_string_append_printf(l_string_ret, "addr: %s\n", (l_addr_str) ? l_addr_str : "-");
-            g_string_append_printf(l_string_ret, "balance: %lld\n", balance);
+            dap_string_append_printf(l_string_ret, "\nwallet: %s\n", l_wallet->name);
+            dap_string_append_printf(l_string_ret, "addr: %s\n", (l_addr_str) ? l_addr_str : "-");
+            dap_string_append_printf(l_string_ret, "balance: %lld\n", balance);
             DAP_DELETE(l_addr_str);
             dap_chain_wallet_close(l_wallet);
         }
         else {
-            g_string_free(l_string_ret, TRUE);
+            dap_string_free(l_string_ret, true);
             set_reply_text(str_reply, "wallet not found");
             return -1;
         }
@@ -1150,10 +1429,10 @@ int com_tx_wallet(int argc, const char ** argv, char **str_reply)
         break;
     }
 
-    char *l_str_ret_tmp = g_string_free(l_string_ret, FALSE);
-    char *str_ret = strdup(l_str_ret_tmp);
+    char *l_str_ret_tmp = dap_string_free(l_string_ret, false);
+    char *str_ret = dap_strdup(l_str_ret_tmp);
     set_reply_text(str_reply, str_ret);
-    g_free(l_str_ret_tmp);
+    DAP_DELETE(l_str_ret_tmp);
     return 0;
 }
 
@@ -1286,34 +1565,34 @@ int com_tx_create(int argc, const char ** argv, char **str_reply)
         dap_chain_node_datum_tx_cache_init(l_key, l_token_name, (dap_chain_addr_t*) l_addr, 1000);
         l_first_start = false;
     }
-    GString *string_ret = g_string_new(NULL);
+    dap_string_t *string_ret = dap_string_new(NULL);
     //g_string_printf(string_ret, "from=%s\nto=%s\nval=%lld\nfee=%s\nval_fee=%lld\n\n",
     //        addr_base58_from, addr_base58_to, value, addr_base58_fee, value_fee);
 
     uint64_t balance2 = dap_chain_datum_tx_cache_calc_balance(addr_to);
     uint64_t balance3 = dap_chain_datum_tx_cache_calc_balance(addr_fee);
     uint64_t balance1 = dap_chain_datum_tx_cache_calc_balance(addr_from);
-    g_string_append_printf(string_ret, "transactions in cache=%d balance w_from=%lld w_to=%lld w_feee=%lld\n",
+    dap_string_append_printf(string_ret, "transactions in cache=%d balance w_from=%lld w_to=%lld w_feee=%lld\n",
             dap_chain_node_datum_tx_cache_count(),
             balance1, balance2, balance3);
 
     int res = dap_chain_datum_tx_ctrl_create_transfer(l_key, addr_from, addr_to, addr_fee, value, value_fee);
-    g_string_append_printf(string_ret, "transfer=%s\n", (res == 1) ? "Ok" : "False");
+    dap_string_append_printf(string_ret, "transfer=%s\n", (res == 1) ? "Ok" : "False");
 
     if(1) {
         uint64_t balance1 = dap_chain_datum_tx_cache_calc_balance(addr_from);
         uint64_t balance2 = dap_chain_datum_tx_cache_calc_balance(addr_to);
         uint64_t balance3 = dap_chain_datum_tx_cache_calc_balance(addr_fee);
-        g_string_append_printf(string_ret, "transactions in cache=%d balance w_from=%lld w_to=%lld w_feee=%lld\n",
+        dap_string_append_printf(string_ret, "transactions in cache=%d balance w_from=%lld w_to=%lld w_feee=%lld\n",
                 dap_chain_node_datum_tx_cache_count(),
                 balance1, balance2, balance3);
     }
 
-    char *str_ret_tmp = g_string_free(string_ret, FALSE);
+    char *str_ret_tmp = dap_string_free(string_ret, false);
     char *str_ret = strdup(str_ret_tmp);
     set_reply_text(str_reply, str_ret);
 
-    g_free(str_ret_tmp);
+    DAP_DELETE(str_ret_tmp);
     DAP_DELETE(addr_to);
     DAP_DELETE(addr_fee);
     dap_chain_wallet_close(wallet_bliss);
@@ -1515,7 +1794,7 @@ int com_tx_verify(int argc, const char ** argv, char **str_reply)
         if(cmd)
         {
             if(str_reply)
-                *str_reply = g_strdup(cmd->doc);
+                *str_reply = dap_strdup(cmd->doc);
             return 1;
         }
         if(str_reply)
diff --git a/dap_chain_node_client.c b/dap_chain_node_client.c
index e7ef53cfc906c0fdde49767862dec8ecba4f5ff9..b3171682fb21cafdb603178e6527326b58477914 100644
--- a/dap_chain_node_client.c
+++ b/dap_chain_node_client.c
@@ -159,26 +159,26 @@ void dap_chain_node_client_close(dap_chain_node_client_t *a_client)
 }
 
 /*
-// callback for dap_client_request_enc() in client_mempool_send_datum()
-static void s_response_proc(dap_client_t *a_client, void *str, size_t str_len)
-{
-    printf("* s_response_proc a_client=%x str=%s str_len=%d\n", a_client, str, str_len);
-    dap_chain_node_client_t *l_client = a_client->_inheritor;
-    assert(l_client);
-    if(l_client) {
-        if(str_len > 0) {
-//            l_client->read_data_t.data = DAP_NEW_Z_SIZE(uint8_t, str_len + 1);
-//          if(l_client->read_data_t.data) {
-//                memcpy(l_client->read_data_t.data, str, str_len);
-//                l_client->read_data_t.data_len = str_len;
-        }
-    }
-    pthread_mutex_lock(&l_client->wait_mutex);
-    l_client->state = NODE_CLIENT_STATE_SENDED;
-    pthread_cond_signal(&l_client->wait_cond);
-    pthread_mutex_unlock(&l_client->wait_mutex);
-}
-*/
+ // callback for dap_client_request_enc() in client_mempool_send_datum()
+ static void s_response_proc(dap_client_t *a_client, void *str, size_t str_len)
+ {
+ printf("* s_response_proc a_client=%x str=%s str_len=%d\n", a_client, str, str_len);
+ dap_chain_node_client_t *l_client = a_client->_inheritor;
+ assert(l_client);
+ if(l_client) {
+ if(str_len > 0) {
+ //            l_client->read_data_t.data = DAP_NEW_Z_SIZE(uint8_t, str_len + 1);
+ //          if(l_client->read_data_t.data) {
+ //                memcpy(l_client->read_data_t.data, str, str_len);
+ //                l_client->read_data_t.data_len = str_len;
+ }
+ }
+ pthread_mutex_lock(&l_client->wait_mutex);
+ l_client->state = NODE_CLIENT_STATE_SENDED;
+ pthread_cond_signal(&l_client->wait_cond);
+ pthread_mutex_unlock(&l_client->wait_mutex);
+ }
+ */
 
 /*// callback for dap_client_request_enc() in client_mempool_send_datum()
  static void s_response_error(dap_client_t *a_client, int val)
@@ -207,13 +207,55 @@ static void s_response_proc(dap_client_t *a_client, void *str, size_t str_len)
  pthread_mutex_unlock(&a_client->wait_mutex);
  }*/
 
-static void dap_chain_node_client_callback(dap_stream_ch_chain_net_pkt_t *a_ch_chain_net, void *a_arg)
+static void dap_chain_node_client_callback(dap_stream_ch_chain_net_pkt_t *a_ch_chain_net, size_t a_data_size,
+        void *a_arg)
 {
-    dap_chain_node_client_t *client = (dap_chain_node_client_t*)a_arg;
+    dap_chain_node_client_t *client = (dap_chain_node_client_t*) a_arg;
     assert(client);
-    if(a_ch_chain_net->hdr.type==STREAM_CH_CHAIN_NET_PKT_TYPE_PONG) {
+    // end of session
+    if(!a_ch_chain_net)
+    {
         pthread_mutex_lock(&client->wait_mutex);
-        client->state = NODE_CLIENT_STATE_PONG;
+        client->state = NODE_CLIENT_STATE_END;
+        pthread_cond_signal(&client->wait_cond);
+        pthread_mutex_unlock(&client->wait_mutex);
+        return;
+    }
+
+    int l_state;
+    //printf("*callback type=%d\n", a_ch_chain_net->hdr.type);
+
+    switch (a_ch_chain_net->hdr.type) {
+    case STREAM_CH_CHAIN_NET_PKT_TYPE_PING:
+        l_state = NODE_CLIENT_STATE_PING;
+        break;
+    case STREAM_CH_CHAIN_NET_PKT_TYPE_PONG:
+        l_state = NODE_CLIENT_STATE_PONG;
+        break;
+    case STREAM_CH_CHAIN_NET_PKT_TYPE_GET_NODE_ADDR:
+        l_state = NODE_CLIENT_STATE_GET_NODE_ADDR;
+        client->recv_data_len = a_data_size;
+        if(client->recv_data_len > 0) {
+            client->recv_data = DAP_NEW_SIZE(uint8_t, a_data_size);
+            memcpy(client->recv_data, a_ch_chain_net->data, a_data_size);
+        }
+
+        break;
+    case STREAM_CH_CHAIN_NET_PKT_TYPE_SET_NODE_ADDR:
+        l_state = NODE_CLIENT_STATE_SET_NODE_ADDR;
+        break;
+//    case STREAM_CH_CHAIN_NET_PKT_TYPE_GLOVAL_DB:
+//        l_state = NODE_CLIENT_STATE_CONNECTED;
+//        break;
+
+    default:
+        l_state = NODE_CLIENT_STATE_ERROR;
+
+    }
+    if(client)
+    {
+        pthread_mutex_lock(&client->wait_mutex);
+        client->state = l_state;
         pthread_cond_signal(&client->wait_cond);
         pthread_mutex_unlock(&client->wait_mutex);
     }
@@ -222,7 +264,7 @@ static void dap_chain_node_client_callback(dap_stream_ch_chain_net_pkt_t *a_ch_c
 /**
  * Send stream request to server
  */
-int dap_chain_node_client_send_chain_request(dap_chain_node_client_t *a_client, uint8_t a_ch_id,
+int dap_chain_node_client_send_chain_net_request(dap_chain_node_client_t *a_client, uint8_t a_ch_id, uint8_t a_type,
         char *a_buf, size_t a_buf_size)
 {
     if(!a_client || a_client->state < NODE_CLIENT_STATE_CONNECTED)
@@ -234,8 +276,8 @@ int dap_chain_node_client_send_chain_request(dap_chain_node_client_t *a_client,
         dap_stream_ch_chain_net_t * l_ch_chain = DAP_STREAM_CH_CHAIN_NET(l_ch);
         l_ch_chain->notify_callback = dap_chain_node_client_callback;
         l_ch_chain->notify_callback_arg = a_client;
-        int l_res = dap_stream_ch_chain_net_pkt_write(l_ch, STREAM_CH_CHAIN_NET_PKT_TYPE_PING, a_buf, a_buf_size);
-        if(l_res <=0)
+        int l_res = dap_stream_ch_chain_net_pkt_write(l_ch, a_type, a_buf, a_buf_size);
+        if(l_res <= 0)
             return -1;
         bool is_ready = true;
         dap_events_socket_set_writable(l_ch->stream->events_socket, is_ready);
@@ -276,11 +318,18 @@ int chain_node_client_wait(dap_chain_node_client_t *a_client, int a_waited_state
     else
         to.tv_nsec = (long) nsec_new;
     // signal waiting
-    int wait = pthread_cond_timedwait(&a_client->wait_cond, &a_client->wait_mutex, &to);
-    if(wait == 0) //0
-        ret = 1;
-    else if(wait == ETIMEDOUT) // 110 260
-        ret = 0;
+    do {
+        int wait = pthread_cond_timedwait(&a_client->wait_cond, &a_client->wait_mutex, &to);
+        if(wait == 0 && a_client->state == a_waited_state) {
+            ret = 1;
+            break;
+        }
+        else if(wait == ETIMEDOUT) { // 110 260
+            ret = 0;
+            break;
+        }
+    }
+    while(1);
     pthread_mutex_unlock(&a_client->wait_mutex);
     return ret;
 }
diff --git a/dap_chain_node_client.h b/dap_chain_node_client.h
index 5f2a0e88cff2c8af1e2230fac8b147127a42e816..40bae27a77a00021579508746446a6b5a4473922 100644
--- a/dap_chain_node_client.h
+++ b/dap_chain_node_client.h
@@ -35,8 +35,11 @@ enum {
     NODE_CLIENT_STATE_CONNECTED,
     //NODE_CLIENT_STATE_SEND,
     //NODE_CLIENT_STATE_SENDED,
+    NODE_CLIENT_STATE_GET_NODE_ADDR,
+    NODE_CLIENT_STATE_SET_NODE_ADDR,
     NODE_CLIENT_STATE_PING,
     NODE_CLIENT_STATE_PONG,
+
     NODE_CLIENT_STATE_END
 };
 
@@ -53,6 +56,8 @@ typedef struct dap_chain_node_client {
     dap_chain_node_client_callback_t callback_stream_connected;
     pthread_cond_t wait_cond;
     pthread_mutex_t wait_mutex;
+    uint8_t *recv_data;
+    size_t recv_data_len;
 } dap_chain_node_client_t;
 
 
@@ -77,7 +82,7 @@ void dap_chain_node_client_close(dap_chain_node_client_t *client);
 /**
  * Send stream request to server
  */
-int dap_chain_node_client_send_chain_request(dap_chain_node_client_t *a_client, uint8_t a_ch_id,
+int dap_chain_node_client_send_chain_net_request(dap_chain_node_client_t *a_client, uint8_t a_ch_id, uint8_t a_type,
         char *a_buf, size_t a_buf_size);
 
 /**
diff --git a/iputils/iputils.c b/iputils/iputils.c
index 0e16de9e96a627a1a61d89a10493d12fb23424e8..07184747f198fcc2a5024374ee46b49de0fc731a 100644
--- a/iputils/iputils.c
+++ b/iputils/iputils.c
@@ -4,7 +4,9 @@
 
 #include <stdio.h>
 #include <stdbool.h>
-#include <glib.h>
+//#include <glib.h>
+#include "dap_common.h"
+#include "dap_strfuncs.h"
 
 static bool LOG_VERBOSE = false;
 
@@ -30,18 +32,18 @@ int log_printf(const char *format, ...)
     int ret = 0;
     if(LOG_VERBOSE)
     {
-        gchar *log_str = NULL;
+        char *log_str = NULL;
         va_list args;
 
         va_start(args, format);
-        log_str = g_strdup_vprintf(format, args);
+        log_str = dap_strdup_vprintf(format, args);
         va_end(args);
 
         if(log_str)
         {
 
             ret = printf(log_str);
-            g_free(log_str);
+            DAP_DELETE(log_str);
         }
     }
     return ret;
diff --git a/iputils/ping.c b/iputils/ping.c
index 491a5e4d7f0d15395149c5979b7799075c69356f..98a62dc4df95a0d2f5d2719a46d61203dd80a6f2 100644
--- a/iputils/ping.c
+++ b/iputils/ping.c
@@ -56,7 +56,9 @@
 #include <netinet/ip_icmp.h>
 #include <ifaddrs.h>
 #include <math.h>
-#include <glib.h>
+//#include <glib.h>
+#include "dap_common.h"
+#include "dap_strfuncs.h"
 
 #ifndef ICMP_FILTER
 #define ICMP_FILTER	1
@@ -547,10 +549,10 @@ int ping_util_common(int type, const char *addr, int count)
         argv[0] = "ping6";
     else
         argv[0] = "ping4";
-    argv[1] = g_strdup_printf("-c%d", count);
+    argv[1] = dap_strdup_printf("-c%d", count);
     argv[2] = addr;
     int status = ping_main(argc, (char**) argv);
-    g_free((char*) argv[1]);
+    DAP_DELETE((char*) argv[1]);
     if(ntransmitted >= 1 && nreceived >= 1)
         return tsum;
     return status;