From 0cd04b74ce476148473dbd76bdd17a811b07c951 Mon Sep 17 00:00:00 2001
From: ANTA <arcticshine999@gmail.com>
Date: Wed, 26 Jun 2019 21:49:51 +0400
Subject: [PATCH] '2317-2'

---
 dap_chain_net.c          | 286 +++++++++++++++++--------
 dap_chain_net.h          |  29 ++-
 dap_chain_node.c         |  21 +-
 dap_chain_node.h         |   3 +-
 dap_chain_node_cli.c     | 440 +++++++++++++++++++++++++++++++++++----
 dap_chain_node_cli.h     |   2 +
 dap_chain_node_cli_cmd.c |  37 +++-
 dap_chain_node_client.c  |  26 ++-
 dap_chain_node_remote.c  |  18 +-
 9 files changed, 707 insertions(+), 155 deletions(-)

diff --git a/dap_chain_net.c b/dap_chain_net.c
index dab23a090c..68df3f1f09 100644
--- a/dap_chain_net.c
+++ b/dap_chain_net.c
@@ -22,8 +22,25 @@
     You should have received a copy of the GNU General Public License
     along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
 */
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <stdlib.h>
 #include <stddef.h>
+#include <stdint.h>
 #include <string.h>
+
+#ifdef WIN32
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0600
+#include <winsock2.h>
+#include <windows.h>
+#include <mswsock.h>
+#include <ws2tcpip.h>
+#include <io.h>
+#include <wepoll.h>
+#endif
+
 #include <pthread.h>
 
 #include "uthash.h"
@@ -62,21 +79,30 @@
 
 #define LOG_TAG "chain_net"
 
+#define F_DAP_CHAIN_NET_SHUTDOWN  ( 1 << 9 )
+
 /**
   * @struct dap_chain_net_pvt
   * @details Private part of chain_net dap object
   */
-typedef struct dap_chain_net_pvt{
+typedef struct dap_chain_net_pvt {
+
     pthread_t proc_tid;
+#ifndef _WIN32
     pthread_cond_t state_proc_cond;
+#else
+    HANDLE state_proc_cond;
+#endif
     pthread_mutex_t state_mutex;
+
     dap_chain_node_role_t node_role;
-    uint8_t padding2[4];
+    uint32_t  flags;
+//    uint8_t padding2[4];
 
-    dap_chain_node_addr_t * node_addr;
-    dap_chain_node_info_t * node_info; // Current node's info
+    dap_chain_node_addr_t *node_addr;
+    dap_chain_node_info_t *node_info; // Current node's info
 
-    dap_chain_node_client_t * links;
+    dap_chain_node_client_t *links;
     size_t links_count;
 
     dap_chain_node_addr_t *links_addrs;
@@ -91,6 +117,7 @@ typedef struct dap_chain_net_pvt{
     dap_chain_net_state_t state;
     dap_chain_net_state_t state_prev;
     dap_chain_net_state_t state_target;
+
 } dap_chain_net_pvt_t;
 
 typedef struct dap_chain_net_item{
@@ -100,7 +127,7 @@ typedef struct dap_chain_net_item{
     UT_hash_handle hh;
 } dap_chain_net_item_t;
 
-#define PVT(a) ( (dap_chain_net_pvt_t *) (void*) a->pvt )
+#define PVT(a)   ( (dap_chain_net_pvt_t *) (void*) a->pvt )
 #define PVT_S(a) ( (dap_chain_net_pvt_t *) (void*) a.pvt )
 
 static dap_chain_net_item_t * s_net_items = NULL;
@@ -147,15 +174,24 @@ inline static const char * s_net_state_to_str(dap_chain_net_state_t l_state)
  * @param a_net
  * @param a_new_state
  */
-int dap_chain_net_state_go_to(dap_chain_net_t * a_net, dap_chain_net_state_t a_new_state)
+int dap_chain_net_state_go_to( dap_chain_net_t *a_net, dap_chain_net_state_t a_new_state )
 {
-    pthread_mutex_lock( &PVT(a_net)->state_mutex);
-    if (PVT(a_net)->state_target == a_new_state){
-        log_it(L_WARNING,"Already going to state %s",s_net_state_to_str(a_new_state));
+    pthread_mutex_lock( &PVT(a_net)->state_mutex );
+
+    if ( PVT(a_net)->state_target == a_new_state ) {
+        log_it( L_WARNING,"Already going to state %s",s_net_state_to_str(a_new_state) );
     }
+
     PVT(a_net)->state_target = a_new_state;
-    pthread_cond_signal(&PVT(a_net)->state_proc_cond);
-    pthread_mutex_unlock( &PVT(a_net)->state_mutex);
+
+#ifndef _WIN32
+    pthread_cond_signal( &PVT(a_net)->state_proc_cond );
+#else
+    SetEvent( PVT(a_net)->state_proc_cond );
+#endif
+
+    pthread_mutex_unlock( &PVT(a_net)->state_mutex );
+
     return 0;
 }
 
@@ -191,31 +227,42 @@ static void s_gbd_history_callback_notify (void * a_arg, const char a_op_code, c
  * @brief s_net_states_proc
  * @param l_net
  */
-static int s_net_states_proc(dap_chain_net_t * l_net)
+static int s_net_states_proc( dap_chain_net_t *l_net )
 {
-    dap_chain_net_pvt_t *pvt_debug = PVT(l_net);
-    int ret=0;
+//    dap_chain_net_pvt_t *pvt_debug = PVT( l_net );
+    int ret = 0;
+
 lb_proc_state:
-    pthread_mutex_lock(&PVT(l_net)->state_mutex );
-    switch ( PVT(l_net)->state ){
-        case NET_STATE_OFFLINE:{
+
+    pthread_mutex_lock( &PVT(l_net)->state_mutex );
+
+    switch ( PVT(l_net)->state ) {
+
+        case NET_STATE_OFFLINE: {
             log_it(L_NOTICE,"%s.state: NET_STATE_OFFLINE",l_net->pub.name);
-            dap_chain_node_client_t * l_node_client = NULL, *l_node_client_tmp = NULL;
+
+            dap_chain_node_client_t *l_node_client = NULL, *l_node_client_tmp = NULL;
+
             HASH_ITER(hh,PVT(l_net)->links,l_node_client,l_node_client_tmp){
                 HASH_DEL(PVT(l_net)->links, l_node_client);
                 dap_chain_node_client_close(l_node_client);
             }
+
             PVT(l_net)->links_addrs_count = 0;
+
             if ( PVT(l_net)->links_addrs )
                 DAP_DELETE(PVT(l_net)->links_addrs);
+
             PVT(l_net)->links_addrs = NULL;
 
-            if ( PVT(l_net)->state_target != NET_STATE_OFFLINE ){
+            if ( PVT(l_net)->state_target != NET_STATE_OFFLINE ) {
                 PVT(l_net)->state = NET_STATE_LINKS_PREPARE;
                 pthread_mutex_unlock(&PVT(l_net)->state_mutex );
                 goto lb_proc_state;
             }
+
         } break;
+
         case NET_STATE_LINKS_PREPARE:{
             log_it(L_NOTICE,"%s.state: NET_STATE_LINKS_PREPARE",l_net->pub.name);
             switch (PVT(l_net)->node_role.enums) {
@@ -302,6 +349,7 @@ lb_proc_state:
                 PVT(l_net)->state = NET_STATE_OFFLINE;
             }
         } pthread_mutex_unlock(&PVT(l_net)->state_mutex ); goto lb_proc_state;
+
         case NET_STATE_LINKS_CONNECTING:{
             log_it(L_NOTICE,"%s.state: NET_STATE_LINKS_CONNECTING",l_net->pub.name);
             size_t l_links_established = 0;
@@ -338,6 +386,7 @@ lb_proc_state:
                 PVT(l_net)->state_target = NET_STATE_OFFLINE ;
             }
         } pthread_mutex_unlock(&PVT(l_net)->state_mutex ); goto lb_proc_state;
+
         case NET_STATE_LINKS_ESTABLISHED:{
             log_it(L_NOTICE,"%s.state: NET_STATE_LINKS_ESTABLISHED",l_net->pub.name);
             switch (PVT(l_net)->state_target) {
@@ -555,33 +604,49 @@ lb_proc_state:
  * @param a_cfg Network1 configuration
  * @return
  */
-static void * s_net_proc_thread ( void * a_net)
+static void *s_net_proc_thread ( void *a_net )
 {
-    dap_chain_net_t * l_net = (dap_chain_net_t *) a_net;
-    bool is_looping = true ;
-    while( is_looping ) {
-        s_net_states_proc(l_net);
-        pthread_mutex_lock( &PVT(l_net)->state_mutex );
+    dap_chain_net_t *l_net = (dap_chain_net_t *)a_net;
+    dap_chain_net_pvt_t *p_net = (dap_chain_net_pvt_t *)(void *)l_net->pvt;
+
+    const uint64_t l_timeout_ms = 20000;// 20 sec
+
+    while( !(p_net->flags & F_DAP_CHAIN_NET_SHUTDOWN) ) {
+
+        s_net_states_proc( l_net );
+    #ifndef _WIN32
+        pthread_mutex_lock( &p_net->state_mutex );
 
-        int l_timeout_ms = 20000;// 20 sec
         // prepare for signal waiting
+
         struct timespec l_to;
-        clock_gettime(CLOCK_MONOTONIC, &l_to);
-        int64_t l_nsec_new = l_to.tv_nsec + l_timeout_ms * 1000000ll;
+        clock_gettime( CLOCK_MONOTONIC, &l_to );
+        //int64_t l_nsec_new = l_to.tv_nsec + l_timeout_ms * 1000000ll;
+
+        l_to.tv_sec += l_timeout_ms / 1000;
+
         // if the new number of nanoseconds is more than a second
-        if(l_nsec_new > (long) 1e9) {
-            l_to.tv_sec += l_nsec_new / (long) 1e9;
-            l_to.tv_nsec = l_nsec_new % (long) 1e9;
-        }
-        else
-            l_to.tv_nsec = (long) l_nsec_new;
+        //if(l_nsec_new > (long) 1e9) {
+        //    l_to.tv_sec += l_nsec_new / (long) 1e9;
+        //    l_to.tv_nsec = l_nsec_new % (long) 1e9;
+        //}
+        //else
+        //    l_to.tv_nsec = (long) l_nsec_new;
+
         // signal waiting
-        pthread_cond_timedwait(&PVT(l_net)->state_proc_cond, &PVT(l_net)->state_mutex, &l_to);
+        pthread_cond_timedwait( &p_net->state_proc_cond, &p_net->state_mutex, &l_to );
+
         //pthread_cond_wait(&PVT(l_net)->state_proc_cond,&PVT(l_net)->state_mutex);
-        pthread_mutex_unlock( &PVT(l_net)->state_mutex );
-        log_it( L_DEBUG, "Waked up net proHASH_COUNT( c thread");
+        pthread_mutex_unlock( &p_net->state_mutex );
+    #else // WIN32
+
+        WaitForSingleObject( p_net->state_proc_cond, (uint32_t)l_timeout_ms );
+
+    #endif
 
+        log_it( L_DEBUG, "Waked up net proHASH_COUNT( c thread" );
     }
+
     return NULL;
 }
 
@@ -602,13 +667,25 @@ static void s_net_proc_thread_start( dap_chain_net_t * a_net )
  */
 static void s_net_proc_kill( dap_chain_net_t * a_net )
 {
-    if ( PVT(a_net)->proc_tid ) {
-        pthread_cond_signal(& PVT(a_net)->state_proc_cond);
-        log_it(L_NOTICE,"Sent KILL signal to the net process thread %d, waiting for shutdown...",PVT(a_net)->proc_tid);
-        pthread_join( PVT(a_net)->proc_tid , NULL);
-        log_it(L_NOTICE,"Net process thread %d shutted down",PVT(a_net)->proc_tid);
-        PVT(a_net)->proc_tid = 0;
-    }
+    if ( !PVT(a_net)->proc_tid )
+        return;
+
+    log_it( L_NOTICE,"Sent KILL signal to the net process thread %d, waiting for shutdown...", PVT(a_net)->proc_tid );
+
+    PVT(a_net)->flags |= F_DAP_CHAIN_NET_SHUTDOWN;
+
+#ifndef _WIN32
+    pthread_cond_signal( &PVT(a_net)->state_proc_cond );
+#else
+    SetEvent( PVT(a_net)->state_proc_cond );
+#endif
+
+    pthread_join( PVT(a_net)->proc_tid , NULL );
+    log_it( L_NOTICE,"Net process thread %d shutted down", PVT(a_net)->proc_tid );
+
+    PVT(a_net)->proc_tid = 0;
+
+    return;
 }
 
 /**
@@ -619,17 +696,25 @@ static void s_net_proc_kill( dap_chain_net_t * a_net )
  * @param a_node_name
  * @return
  */
-static dap_chain_net_t * s_net_new(const char * a_id, const char * a_name ,
+static dap_chain_net_t *s_net_new(const char * a_id, const char * a_name ,
                                     const char * a_node_role)
 {
-    dap_chain_net_t * ret = DAP_NEW_Z_SIZE (dap_chain_net_t, sizeof (ret->pub)+ sizeof (dap_chain_net_pvt_t) );
+    dap_chain_net_t *ret = DAP_NEW_Z_SIZE( dap_chain_net_t, sizeof(ret->pub) + sizeof(dap_chain_net_pvt_t) );
     ret->pub.name = strdup( a_name );
-    pthread_mutex_init( &PVT(ret)->state_mutex, NULL);
+
+    pthread_mutex_init( &PVT(ret)->state_mutex, NULL );
+
+#ifndef _WIN32
     pthread_condattr_t l_attr;
-    pthread_condattr_init(&l_attr);
-    pthread_condattr_setclock(&l_attr, CLOCK_MONOTONIC);
-    pthread_cond_init( &PVT(ret)->state_proc_cond, &l_attr);
-    if ( sscanf(a_id,"0x%016lx", &ret->pub.id.uint64 ) == 1 ){
+    pthread_condattr_init( &l_attr );
+    pthread_condattr_setclock( &l_attr, CLOCK_MONOTONIC );
+    pthread_cond_init( &PVT(ret)->state_proc_cond, &l_attr );
+#else
+    PVT(ret)->state_proc_cond = CreateEventA( NULL, FALSE, FALSE, NULL );
+#endif
+
+    //    if ( sscanf(a_id,"0x%016lx", &ret->pub.id.uint64 ) == 1 ){
+    if ( sscanf(a_id,"0x%016llx", &ret->pub.id.uint64 ) == 1 ){
         if (strcmp (a_node_role, "root_master")==0){
             PVT(ret)->node_role.enums = NODE_ROLE_ROOT_MASTER;
             log_it (L_NOTICE, "Node role \"root master\" selected");
@@ -689,6 +774,7 @@ void dap_chain_net_delete( dap_chain_net_t * a_net )
 int dap_chain_net_init()
 {
     dap_chain_node_cli_cmd_item_create ("net", s_cli_net, "Network commands",
+
         "net -net <chain net name> go < online | offline >\n"
             "\tFind and establish links and stay online\n"
         "net -net <chain net name> get status\n"
@@ -700,6 +786,7 @@ int dap_chain_net_init()
         "net -net <chain net name> link < list | add | del | info | establish >\n"
             "\tList,add,del, dump or establish links\n\n"
                                         );
+
     s_seed_mode = dap_config_get_item_bool_default(g_config,"general","seed_mode",false);
     dap_chain_global_db_add_history_group_prefix("global");
 
@@ -709,19 +796,40 @@ int dap_chain_net_init()
 
 void dap_chain_net_load_all()
 {
-    char * l_net_dir_str = dap_strdup_printf("%s/network", dap_config_path());
-    DIR * l_net_dir = opendir( l_net_dir_str);
+    char * l_net_dir_str = dap_strdup_printf( "%s/network", dap_config_path() );
+
+//    printf("Scaning dir %s ...\n", l_net_dir_str );
+//    Sleep( 1000 );
+
+    DIR * l_net_dir = opendir( l_net_dir_str );
     DAP_DELETE (l_net_dir_str);
+
     if ( l_net_dir ){
-        struct dirent * l_dir_entry;
-        while ( (l_dir_entry = readdir(l_net_dir) )!= NULL ){
-            if (l_dir_entry->d_name[0]=='\0' || l_dir_entry->d_name[0]=='.')
+
+        struct dirent *l_dir_entry;
+
+        log_it( L_INFO, "*********************************************************" );
+//        printf("OPA OPA OPA\n");
+//        Sleep( 1000 );
+
+        while ( (l_dir_entry = readdir(l_net_dir) ) != NULL ) {
+
+            if ( !l_dir_entry->d_name[0] || l_dir_entry->d_name[0] == '.' )
                 continue;
-            log_it(L_DEBUG,"Network config %s try to load", l_dir_entry->d_name);
-            char* l_dot_pos = rindex(l_dir_entry->d_name,'.');
+
+            log_it( L_INFO, "Network config %s try to load", l_dir_entry->d_name );
+
+//            char* l_dot_pos = rindex(l_dir_entry->d_name,'.');
+
+            char* l_dot_pos = strchr(l_dir_entry->d_name,'.');
+
             if ( l_dot_pos )
-                *l_dot_pos = '\0';
-            s_net_load(l_dir_entry->d_name );
+                *l_dot_pos = 0;
+
+//            log_it( L_INFO, "*********************************************************" );
+//            Sleep( 5000 );
+
+            s_net_load( l_dir_entry->d_name );
         }
     }
 }
@@ -733,18 +841,21 @@ void dap_chain_net_load_all()
  * @param str_reply
  * @return
  */
-static int s_cli_net(int argc, char ** argv, char **a_str_reply)
+static int s_cli_net( int argc, char **argv, char **a_str_reply )
 {
-    int arg_index=1;
+    int arg_index = 1;
     dap_chain_net_t * l_net = NULL;
 
-    int ret = dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index,argc,argv,a_str_reply,NULL,&l_net);
-    if ( l_net ){
-        const char * l_sync_str = NULL;
-        const char * l_links_str = NULL;
-        const char * l_go_str = NULL;
-        const char * l_get_str = NULL;
-        const char * l_stats_str = NULL;
+    int ret = dap_chain_node_cli_cmd_values_parse_net_chain( &arg_index, argc, argv, a_str_reply, NULL, &l_net );
+
+    if ( l_net ) {
+
+        const char *l_sync_str = NULL;
+        const char *l_links_str = NULL;
+        const char *l_go_str = NULL;
+        const char *l_get_str = NULL;
+        const char *l_stats_str = NULL;
+
         dap_chain_node_cli_find_option_val(argv, arg_index, argc, "sync", &l_sync_str);
         dap_chain_node_cli_find_option_val(argv, arg_index, argc, "link", &l_links_str);
         dap_chain_node_cli_find_option_val(argv, arg_index, argc, "go", &l_go_str);
@@ -752,29 +863,31 @@ static int s_cli_net(int argc, char ** argv, char **a_str_reply)
         dap_chain_node_cli_find_option_val(argv, arg_index, argc, "stats", &l_stats_str);
 
         if ( l_stats_str ){
+
             if ( strcmp(l_stats_str,"tx") == 0 ) {
-                const char * l_to_str = NULL;
+
+                const char *l_to_str = NULL;
                 struct tm l_to_tm = {0};
 
-                const char * l_from_str = NULL;
+                const char *l_from_str = NULL;
                 struct tm l_from_tm = {0};
 
-                const char * l_prev_sec_str = NULL;
+                const char *l_prev_sec_str = NULL;
                 time_t l_prev_sec_ts;
 
                 const char c_time_fmt[]="%Y-%m-%d_%H:%M:%S";
 
                 // Read from/to time
-                dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-from", &l_from_str);
-                dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-to", &l_to_str);
-                dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-prev_sec", &l_prev_sec_str);
+                dap_chain_node_cli_find_option_val( argv, arg_index, argc, "-from", &l_from_str );
+                dap_chain_node_cli_find_option_val( argv, arg_index, argc, "-to", &l_to_str );
+                dap_chain_node_cli_find_option_val( argv, arg_index, argc, "-prev_sec", &l_prev_sec_str );
 
-                if (l_from_str ){
-                    strptime(l_from_str,c_time_fmt,&l_from_tm);
+                if (l_from_str ) {
+                    strptime( (char *)l_from_str, c_time_fmt, &l_from_tm );
                 }
 
-                if (l_to_str){
-                    strptime(l_to_str,c_time_fmt,&l_to_tm);
+                if (l_to_str) {
+                    strptime( (char *)l_to_str, c_time_fmt, &l_to_tm );
                 }
 
                 if ( l_to_str == NULL ){ // If not set '-to' - we set up current time
@@ -799,8 +912,9 @@ static int s_cli_net(int argc, char ** argv, char **a_str_reply)
                 // Produce strings
                 char l_from_str_new[50];
                 char l_to_str_new[50];
-                strftime(l_from_str_new, sizeof(l_from_str_new), c_time_fmt,&l_from_tm );
-                strftime(l_to_str_new, sizeof(l_to_str_new), c_time_fmt,&l_to_tm );
+
+                strftime( l_from_str_new, sizeof(l_from_str_new), c_time_fmt,&l_from_tm );
+                strftime( l_to_str_new, sizeof(l_to_str_new), c_time_fmt,&l_to_tm );
 
 
                 dap_string_t * l_ret_str = dap_string_new("Transactions statistics:\n");
@@ -935,7 +1049,7 @@ int s_net_load(const char * a_net_name)
         // Add network to the list
         dap_chain_net_item_t * l_net_item = DAP_NEW_Z( dap_chain_net_item_t);
         dap_chain_net_item_t * l_net_item2 = DAP_NEW_Z( dap_chain_net_item_t);
-        snprintf(l_net_item->name,sizeof (l_net_item->name),"%s"
+        dap_snprintf(l_net_item->name,sizeof (l_net_item->name),"%s"
                      ,dap_config_get_item_str(l_cfg , "general" , "name" ));
         l_net_item->chain_net = l_net;
         l_net_item->net_id.uint64 = l_net->pub.id.uint64;
@@ -989,7 +1103,7 @@ int s_net_load(const char * a_net_name)
                 log_it(L_NOTICE, "Not found alias %s in database, prefill it",PVT(l_net)->seed_aliases[i]);
                 dap_chain_node_info_t * l_node_info = DAP_NEW_Z(dap_chain_node_info_t);
                 l_seed_node_addr = DAP_NEW_Z(dap_chain_node_addr_t);
-                snprintf( l_node_info->hdr.alias,sizeof ( l_node_info->hdr.alias),"%s",PVT(l_net)->seed_aliases[i]);
+                dap_snprintf( l_node_info->hdr.alias,sizeof ( l_node_info->hdr.alias),"%s",PVT(l_net)->seed_aliases[i]);
                 if (sscanf(l_seed_nodes_addrs[i],NODE_ADDR_FP_STR, NODE_ADDR_FPS_ARGS(l_seed_node_addr) ) != 4 ){
                     log_it(L_ERROR,"Wrong address format,  should be like 0123::4567::890AB::CDEF");
                     DAP_DELETE(l_seed_node_addr);
@@ -1068,7 +1182,7 @@ int s_net_load(const char * a_net_name)
         // Init chains
         size_t l_chains_path_size =strlen(dap_config_path())+1+strlen(l_net->pub.name)+1+strlen("network")+1;
         char * l_chains_path = DAP_NEW_Z_SIZE (char,l_chains_path_size);
-        snprintf(l_chains_path,l_chains_path_size,"%s/network/%s",dap_config_path(),l_net->pub.name);
+        dap_snprintf(l_chains_path,l_chains_path_size,"%s/network/%s",dap_config_path(),l_net->pub.name);
         DIR * l_chains_dir = opendir(l_chains_path);
         DAP_DELETE (l_chains_path);
         if ( l_chains_dir ){
@@ -1084,7 +1198,7 @@ int s_net_load(const char * a_net_name)
                     if ( strncmp (l_entry_name+ strlen(l_entry_name)-4,".cfg",4) == 0 ) { // its .cfg file
                         l_entry_name [strlen(l_entry_name)-4] = 0;
                         log_it(L_DEBUG,"Open chain config \"%s\"...",l_entry_name);
-                        snprintf(l_chains_path,l_chains_path_size,"network/%s/%s",l_net->pub.name,l_entry_name);
+                        dap_snprintf(l_chains_path,l_chains_path_size,"network/%s/%s",l_net->pub.name,l_entry_name);
                         //dap_config_open(l_chains_path);
 
                         // Create chain object
diff --git a/dap_chain_net.h b/dap_chain_net.h
index 2a1bf9342e..1a82078e45 100644
--- a/dap_chain_net.h
+++ b/dap_chain_net.h
@@ -23,9 +23,10 @@
     along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
 */
 #pragma once
+#ifndef _WIN32
 #include <sys/socket.h>
 #include <netinet/in.h>
-
+#endif
 #include <stdint.h>
 #include <string.h>
 #include "dap_chain_common.h"
@@ -99,16 +100,22 @@ void dap_chain_net_links_connect(dap_chain_net_t * a_net);
  * @param l_chain
  * @return
  */
-static inline char * dap_chain_net_get_gdb_group_mempool(dap_chain_t * l_chain)
+DAP_STATIC_INLINE char *dap_chain_net_get_gdb_group_mempool( dap_chain_t *l_chain )
 {
-    dap_chain_net_t * l_net = dap_chain_net_by_id(l_chain->net_id);
-    char * l_ret = NULL;
-    if ( l_net ) {
-        const char c_mempool_group_str[]="mempool";
-        size_t l_ret_size =  strlen( l_net->pub.gdb_groups_prefix ) + 1 +
-                strlen( l_chain->name)+1+strlen(c_mempool_group_str)+1;
-        l_ret = DAP_NEW_Z_SIZE(char, l_ret_size);
-        snprintf( l_ret,l_ret_size,"%s.chain-%s.%s",l_net->pub.gdb_groups_prefix,l_chain->name,c_mempool_group_str);
-    }
+    dap_chain_net_t *l_net = dap_chain_net_by_id( l_chain->net_id );
+
+    char *l_ret = NULL;
+    if ( !l_net )
+      return (char *)l_net;
+
+    static const char *c_mempool_group_str = "mempool";
+
+    size_t l_ret_size =  strlen( l_net->pub.gdb_groups_prefix ) + 1 +
+            strlen( l_chain->name) + 1 + strlen(c_mempool_group_str) + 1 + 16;
+
+    l_ret = DAP_NEW_Z_SIZE( char, l_ret_size );
+
+    dap_snprintf( l_ret, l_ret_size, "%s.chain-%s.%s", l_net->pub.gdb_groups_prefix, l_chain->name, c_mempool_group_str );
+
     return l_ret;
 }
diff --git a/dap_chain_node.c b/dap_chain_node.c
index 8358cc143b..68436d2244 100644
--- a/dap_chain_node.c
+++ b/dap_chain_node.c
@@ -19,9 +19,28 @@
  along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#ifdef WIN32
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0600
+#include <winsock2.h>
+#include <windows.h>
+#include <mswsock.h>
+#include <ws2tcpip.h>
+#include <io.h>
+#include <wepoll.h>
+#include <pthread.h>
+#else
 #include <sys/socket.h>
 #include <netinet/in.h>
-#include <string.h>
+#endif
 
 #include "dap_hash.h"
 #include "rand/dap_rand.h"
diff --git a/dap_chain_node.h b/dap_chain_node.h
index 347aef94b6..0780ba53e0 100644
--- a/dap_chain_node.h
+++ b/dap_chain_node.h
@@ -25,9 +25,10 @@
 #include <stddef.h>
 #include <stdbool.h>
 
+#ifndef _WIN32
 #include <sys/socket.h>
 #include <netinet/in.h>
-
+#endif
 #include "dap_common.h"
 #include "dap_chain_common.h"
 #include "dap_chain_global_db.h"
diff --git a/dap_chain_node_cli.c b/dap_chain_node_cli.c
index a65be2bba8..7a9b7a85e0 100644
--- a/dap_chain_node_cli.c
+++ b/dap_chain_node_cli.c
@@ -23,7 +23,6 @@
  along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <pthread.h>
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
@@ -47,10 +46,18 @@ typedef int SOCKET;
 #define INVALID_SOCKET  -1  // for win32 =  (SOCKET)(~0)
 // for Windows
 #else
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0600
 #include <winsock2.h>
-#include <WS2tcpip.h>
+#include <windows.h>
+#include <mswsock.h>
+#include <ws2tcpip.h>
+#include <io.h>
+#include <wepoll.h>
 #endif
 
+#include <pthread.h>
+
 #include "iputils/iputils.h"
 #include "dap_common.h"
 #include "dap_strfuncs.h"
@@ -63,7 +70,14 @@ typedef int SOCKET;
 
 #define LOG_TAG "chain_node_cli"
 
-static SOCKET server_sockfd = -1;
+#define MAX_CONSOLE_CLIENTS 16
+
+static SOCKET server_sockfd = -1; // network or local unix
+uint32_t conServPort = 0;
+
+#ifdef _WIN32
+  #define poll WSAPoll
+#endif
 
 static dap_chain_node_cmd_item_t * s_commands = NULL;
 
@@ -77,7 +91,7 @@ static dap_chain_node_cmd_item_t * s_commands = NULL;
  * return: >0 if data is present to read
  * return: -1 if error
  */
-static int s_poll(int socket, int timeout)
+static int s_poll( int socket, int timeout )
 {
     struct pollfd fds;
     int res;
@@ -163,7 +177,7 @@ long s_recv(SOCKET sock, unsigned char *buf, size_t bufsize, int timeout)
  * timeout - in ms
  * return: string (if waited for final characters) or NULL, if the string requires deletion
  */
-char* s_get_next_str(SOCKET nSocket, int *dwLen, const char *stop_str, bool del_stop_str, int timeout)
+char* s_get_next_str( SOCKET nSocket, int *dwLen, const char *stop_str, bool del_stop_str, int timeout )
 {
     bool bSuccess = false;
     long nRecv = 0; // count of bytes received
@@ -174,6 +188,7 @@ char* s_get_next_str(SOCKET nSocket, int *dwLen, const char *stop_str, bool del_
     size_t lpszBuffer_len = 256;
     char *lpszBuffer = DAP_NEW_Z_SIZE(char, lpszBuffer_len);
     // received string will not be larger than MAX_REPLY_LEN
+
     while(1) //nRecv < MAX_REPLY_LEN)
     {
         // read one byte
@@ -199,7 +214,9 @@ char* s_get_next_str(SOCKET nSocket, int *dwLen, const char *stop_str, bool del_
             }
         }
     };
+
     // end reading
+
     if(bSuccess) {
         // delete the searched string
         if(del_stop_str) {
@@ -215,10 +232,14 @@ char* s_get_next_str(SOCKET nSocket, int *dwLen, const char *stop_str, bool del_
         lpszBuffer = DAP_REALLOC(lpszBuffer,(size_t) *dwLen + 1);
         return lpszBuffer;
     }
+
     // in case of an error or missing string
+
     if(dwLen)
         *dwLen = 0;
+
     free(lpszBuffer);
+
     return NULL;
 }
 
@@ -274,7 +295,7 @@ static void* thread_one_client_func(void *args)
             unsigned int argc = dap_list_length(list);
             // command is found
             if(argc >= 1) {
-            	int l_verbose = 0;
+              int l_verbose = 0;
                 char *cmd_name = list->data;
                 list = dap_list_next(list);
                 // execute command
@@ -308,9 +329,9 @@ static void* thread_one_client_func(void *args)
                 }
                 char *reply_body;
                 if(l_verbose)
-                	reply_body = dap_strdup_printf("%d\r\nret_code: %d\r\n%s\r\n", res, res, (str_reply) ? str_reply : "");
+                  reply_body = dap_strdup_printf("%d\r\nret_code: %d\r\n%s\r\n", res, res, (str_reply) ? str_reply : "");
                 else
-                	reply_body = dap_strdup_printf("%d\r\n%s\r\n", res, (str_reply) ? str_reply : "");
+                  reply_body = dap_strdup_printf("%d\r\n%s\r\n", res, (str_reply) ? str_reply : "");
                 // return the result of the command function
                 char *reply_str = dap_strdup_printf("HTTP/1.1 200 OK\r\n"
                                                     "Content-Length: %d\r\n\r\n"
@@ -333,6 +354,278 @@ static void* thread_one_client_func(void *args)
     return NULL;
 }
 
+#ifdef _WIN32
+
+char *p_get_next_str( HANDLE hPipe, int *dwLen, const char *stop_str, bool del_stop_str, int timeout )
+{
+    bool bSuccess = false;
+    long nRecv = 0; // count of bytes received
+    size_t stop_str_len = (stop_str) ? strlen(stop_str) : 0;
+    // if there is nothing to look for
+
+    if(!stop_str_len)
+        return NULL;
+
+    size_t lpszBuffer_len = 256;
+    char *lpszBuffer = DAP_NEW_Z_SIZE(char, lpszBuffer_len);
+    // received string will not be larger than MAX_REPLY_LEN
+
+    while( 1 ) //nRecv < MAX_REPLY_LEN)
+    {
+      long ret = 0;
+        // read one byte
+//        long ret = s_recv( nSocket, (unsigned char *) (lpszBuffer + nRecv), 1, timeout);
+
+      bSuccess = ReadFile( hPipe, lpszBuffer + nRecv,
+         lpszBuffer_len - nRecv, (LPDWORD)&ret, NULL );
+
+        //int ret = recv(nSocket,lpszBuffer+nRecv,1, 0);
+        if ( ret <= 0 || !bSuccess )
+            break;
+
+        nRecv += ret;
+        //printf("**debug** socket=%d read  %d bytes '%0s'",nSocket, ret, (lpszBuffer + nRecv));
+
+        while((nRecv + 1) >= (long) lpszBuffer_len)
+        {
+            lpszBuffer_len *= 2;
+            lpszBuffer = (char*) realloc(lpszBuffer, lpszBuffer_len);
+        }
+
+        // search for the required string
+        if(nRecv >=  (long) stop_str_len) {
+            // found the required string
+            if(!strncasecmp(lpszBuffer + nRecv - stop_str_len, stop_str, stop_str_len)) {
+                bSuccess = true;
+                break;
+            }
+        }
+    };
+
+    // end reading
+
+    if(bSuccess) {
+        // delete the searched string
+        if(del_stop_str) {
+            lpszBuffer[nRecv -  (long) stop_str_len] = '\0';
+            if(dwLen)
+                *dwLen =(int) nRecv - (int) stop_str_len;
+        }
+        else {
+            lpszBuffer[nRecv] = '\0';
+            if(dwLen)
+                *dwLen = (int) nRecv;
+        }
+        lpszBuffer = DAP_REALLOC(lpszBuffer,(size_t) *dwLen + 1);
+        return lpszBuffer;
+    }
+
+    // in case of an error or missing string
+
+    if(dwLen)
+        *dwLen = 0;
+
+    free(lpszBuffer);
+
+    return NULL;
+}
+
+
+/**
+ * threading function for processing a request from a client
+ */
+static void *thread_pipe_client_func( void *args )
+{
+    HANDLE hPipe = (HANDLE)args;
+
+//    SOCKET newsockfd = (SOCKET) (intptr_t) args;
+    log_it(L_INFO, "new connection pipe = %X", hPipe );
+
+    int str_len, marker = 0;
+    int timeout = 5000; // 5 sec
+    int argc = 0;
+
+    dap_list_t *cmd_param_list = NULL;
+
+    while( 1 )
+    {
+        // wait data from client
+//        int is_data = s_poll( newsockfd, timeout );
+        // timeout
+//        if(!is_data)
+//            continue;
+        // error (may be socket closed)
+//        if(is_data < 0)
+//            break;
+
+//        int is_valid = is_valid_socket(newsockfd);
+//        if(!is_valid)
+//        {
+//            break;
+//        }
+
+        // receiving http header
+        char *str_header = p_get_next_str( hPipe, &str_len, "\r\n", true, timeout );
+
+        // bad format
+        if(!str_header)
+            break;
+
+        if ( str_header && strlen(str_header) == 0) {
+            marker++;
+            if(marker == 1)
+                continue;
+        }
+
+        // filling parameters of command
+        if ( marker == 1 ) {
+            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 ) {
+
+            dap_list_t *list = cmd_param_list;
+            // form command
+
+            unsigned int argc = dap_list_length( list );
+            // command is found
+
+            if ( argc >= 1) {
+
+                int l_verbose = 0;
+                char *cmd_name = list->data;
+                list = dap_list_next( list );
+
+                // execute command
+                char *str_cmd = dap_strdup_printf( "%s", cmd_name );
+                dap_chain_node_cmd_item_t *l_cmd = dap_chain_node_cli_cmd_find( cmd_name );
+                int res = -1;
+                char *str_reply = NULL;
+
+                if ( l_cmd ) {
+
+                    while( 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 **l_argv = dap_strsplit( str_cmd, ";", -1 );
+                    // Call the command function
+
+                    if ( l_cmd &&  l_argv && l_cmd->func )
+                        res = (* (l_cmd->func))( argc, l_argv, &str_reply );
+
+                    else if ( l_cmd ) {
+                        log_it(L_WARNING,"NULL arguments for input for command \"%s\"", str_cmd );
+                    }else {
+                        log_it(L_WARNING,"No function for command \"%s\" but it registred?!", str_cmd );
+                    }
+
+                    // find '-verbose' command
+                    l_verbose = dap_chain_node_cli_find_option_val( l_argv, 1, argc, "-verbose", NULL );
+                    dap_strfreev( l_argv );
+
+                } else {
+                    str_reply = dap_strdup_printf("can't recognize command = %s", str_cmd );
+                    log_it( L_ERROR, str_reply );
+                }
+
+                char *reply_body;
+
+                if(l_verbose)
+                  reply_body = dap_strdup_printf("%d\r\nret_code: %d\r\n%s\r\n", res, res, (str_reply) ? str_reply : "");
+                else
+                  reply_body = dap_strdup_printf("%d\r\n%s\r\n", res, (str_reply) ? str_reply : "");
+
+                // return the result of the command function
+                char *reply_str = dap_strdup_printf( "HTTP/1.1 200 OK\r\n"
+                                                    "Content-Length: %d\r\n\r\n"
+                                                    "%s",
+                        strlen(reply_body), reply_body );
+
+                int ret;// = send( newsockfd, reply_str, strlen(reply_str) ,0 );
+
+                WriteFile( hPipe, reply_str, strlen(reply_str), (LPDWORD)&ret, NULL );
+
+                DAP_DELETE(str_reply);
+                DAP_DELETE(reply_str);
+                DAP_DELETE(reply_body);
+
+                DAP_DELETE(str_cmd);
+            }
+            dap_list_free_full(cmd_param_list, free);
+            break;
+        }
+    }
+
+    // close connection
+//    int cs = closesocket(newsockfd);
+
+    log_it( L_INFO, "close connection pipe = %X", hPipe );
+
+    FlushFileBuffers( hPipe ); 
+    DisconnectNamedPipe( hPipe ); 
+    CloseHandle( hPipe ); 
+
+    return NULL;
+}
+
+
+/**
+ * main threading server function pipe win32
+ */
+static void* thread_pipe_func( void *args )
+{
+   BOOL   fConnected = FALSE; 
+   pthread_t threadId;
+   HANDLE hPipe = INVALID_HANDLE_VALUE, hThread = NULL; 
+   static const char *cPipeName = "\\\\.\\pipe\\node_cli.pipe"; 
+
+   for (;;) 
+   { 
+///      printf( "\nPipe Server: Main thread awaiting client connection on %s\n", lpszPipename );
+
+      hPipe = CreateNamedPipe( 
+          cPipeName,                // pipe name 
+          PIPE_ACCESS_DUPLEX,       // read/write access 
+          PIPE_TYPE_MESSAGE |       // message type pipe 
+          PIPE_READMODE_MESSAGE |   // message-read mode 
+          PIPE_WAIT,                // blocking mode 
+          PIPE_UNLIMITED_INSTANCES, // max. instances  
+          4096,                     // output buffer size 
+          4096,                     // input buffer size 
+          0,                        // client time-out 
+          NULL );                   // default security attribute 
+
+      if ( hPipe == INVALID_HANDLE_VALUE ) {
+          log_it( L_ERROR, "CreateNamedPipe failed, GLE = %d.\n", GetLastError() );
+          return NULL;
+      }
+  
+      fConnected = ConnectNamedPipe( hPipe, NULL ) ? TRUE : ( GetLastError() == ERROR_PIPE_CONNECTED ); 
+ 
+      if ( fConnected )
+      { 
+        log_it( L_INFO, "Client %X connected, creating a processing thread.\n", hPipe ); 
+
+        pthread_create( &threadId, NULL, thread_pipe_client_func, hPipe );
+        pthread_detach( threadId );
+      } 
+      else 
+         CloseHandle( hPipe );
+    } 
+
+    return NULL;
+}
+#endif
+
 /**
  * main threading server function
  */
@@ -340,7 +633,7 @@ static void* thread_main_func(void *args)
 {
     SOCKET sockfd = (SOCKET) (intptr_t) args;
     SOCKET newsockfd;
-    log_it(L_INFO, "Server start socket=%s", UNIX_SOCKET_FILE);
+    log_it( L_INFO, "Server start socket = %s", UNIX_SOCKET_FILE );
     // wait of clients
     while(1)
     {
@@ -425,7 +718,7 @@ int dap_chain_node_cli_find_option_val( char** argv, int arg_start, int arg_end,
 void dap_chain_node_cli_cmd_item_create(const char * a_name, cmdfunc_t *a_func, const char *a_doc, const char *a_doc_ex)
 {
     dap_chain_node_cmd_item_t *l_cmd_item = DAP_NEW_Z(dap_chain_node_cmd_item_t);
-    snprintf(l_cmd_item->name,sizeof (l_cmd_item->name),"%s",a_name);
+    dap_snprintf(l_cmd_item->name,sizeof (l_cmd_item->name),"%s",a_name);
     l_cmd_item->doc = strdup( a_doc);
     l_cmd_item->doc_ex = strdup( a_doc_ex);
     l_cmd_item->func = a_func;
@@ -463,9 +756,20 @@ dap_chain_node_cmd_item_t* dap_chain_node_cli_cmd_find(const char *a_name)
  */
 int dap_chain_node_cli_init(dap_config_t * g_config)
 {
-    struct sockaddr_un server = { AF_UNIX, UNIX_SOCKET_FILE };
-    //server.sun_family = AF_UNIX;
-    //strcpy(server.sun_path, SOCKET_FILE);
+#ifndef _WIN32
+    struct sockaddr_un lserver_addr = { AF_UNIX, UNIX_SOCKET_FILE };
+#endif
+    struct sockaddr_in server_addr;
+    SOCKET sockfd = -1;
+
+    bool bConServerEnabled = dap_config_get_item_bool_default( g_config, "conserver", "enabled", true );
+
+    if ( !bConServerEnabled ) { 
+
+        log_it( L_WARNING, "Console Server is dissabled." );
+        return 0;
+    }
+
     dap_chain_node_cli_cmd_item_create ("global_db", com_global_db, "Work with global database",
            "global_db wallet_info set -addr <wallet address> -cell <cell id> \n\n"
            "global_db cells add -cell <cell id> \n\n"
@@ -473,6 +777,7 @@ int dap_chain_node_cli_init(dap_config_t * g_config)
                     "global_db node del  -net <net name> -addr <node address> | -alias <node alias>\n\n"
                     "global_db node link {add|del}  -net <net name> {-addr <node address> | -alias <node alias>} -link <node address>\n\n"
                         );
+
     dap_chain_node_cli_cmd_item_create ("node", com_node, "Work with node",
             "node alias {<node address> | -alias <node alias>}\n\n"
                     "node connect {<node address> | -alias <node alias>}\n\n"
@@ -534,47 +839,98 @@ int dap_chain_node_cli_init(dap_config_t * g_config)
     dap_chain_node_cli_cmd_item_create ("print_log", com_print_log, "Print log info",
                 "print_log [ts_after <timestamp >] [limit <line numbers>]\n" );
 
+    // create thread for waiting of clients
+    pthread_t threadId;
 
-    // init client for handshake
+    conServPort = (uint16_t)dap_config_get_item_int32_default( g_config, "conserver", "listen_port_tcp", 9999 );
 
-    SOCKET sockfd;
+    if ( !conServPort ) { 
 
-    if(server_sockfd >= 0) {
-        dap_chain_node_cli_delete();
-        server_sockfd = 0;
-    }
+        log_it( L_INFO, "Console Server port 0 - local mode" );
+
+      #ifndef _WIN32
+
+        if ( server_sockfd >= 0 ) {
+            dap_chain_node_cli_delete( );
+            server_sockfd = 0;
+        }
+
+        // create socket
+        sockfd = socket( AF_UNIX, SOCK_STREAM, 0 );
+        if( sockfd == INVALID_SOCKET )
+            return -1;
+
+        int gdsg = sizeof(struct sockaddr_un);
+
+        if ( access( UNIX_SOCKET_FILE, R_OK) != -1 )
+            unlink( UNIX_SOCKET_FILE );
+
+        // connecting the address with a socket
+        if( bind(sockfd, (const struct sockaddr*) &server, sizeof(struct sockaddr_un)) == SOCKET_ERROR) {
+            // errno = EACCES  13  Permission denied
+            if ( errno == EACCES ) // EACCES=13
+                log_it( L_ERROR, "Server can't start(err=%d). Can't create file=%s [Permission denied]", errno,
+                        UNIX_SOCKET_FILE );
+            else
+                log_it( L_ERROR, "Server can't start(err=%d). May be problem with file=%s?", errno, UNIX_SOCKET_FILE );
+            closesocket( sockfd );
+            return -1;
+        }
+
+      #else
+
+    Sleep( 3000 );
+
+        if( pthread_create(&threadId, NULL, thread_pipe_func, (void*) (intptr_t) sockfd) != 0 ) {
+            closesocket( sockfd );
+            return -1;
+        }
+
+        return 0;
+      #endif
 
-    // create socket
-    if((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) == INVALID_SOCKET)
-        return -1;
-    int gdsg = sizeof(struct sockaddr_un);
-    if(access( UNIX_SOCKET_FILE, R_OK) != -1)
-            {
-        unlink(UNIX_SOCKET_FILE);
     }
-    // connecting the address with a socket
-    if(bind(sockfd, (const struct sockaddr*) &server, sizeof(struct sockaddr_un)) == SOCKET_ERROR) {
-        // errno = EACCES  13  Permission denied
-        if(errno == EACCES) // EACCES=13
-            log_it(L_ERROR, "Server can't start(err=%d). Can't create file=%s [Permission denied]", errno,
-                    UNIX_SOCKET_FILE);
-        else
-            log_it(L_ERROR, "Server can't start(err=%d). May be problem with file=%s?", errno, UNIX_SOCKET_FILE);
-        closesocket(sockfd);
-        return -1;
+    else {
+
+        char *listen_addr = dap_config_get_item_str_default( g_config,
+                                                                       "conserver",
+                                                                      "listen_address",
+                                                                      "0.0.0.0" );
+
+        log_it( L_INFO, "Console Server: listen addr %s:%u ", listen_addr, conServPort );
+ 
+        server_addr.sin_family = AF_INET; 
+        inet_pton( AF_INET, listen_addr, &server_addr.sin_addr );
+        //server.sin_addr.s_addr = htonl( INADDR_ANY );
+        server_addr.sin_port = htons( (uint16_t)conServPort );
+
+        // create socket
+        if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET ) {
+            log_it( L_ERROR, "Console Server: can't create socket, err %X", errno );
+            return -1;
+        }
+
+        // connecting the address with a socket
+        if ( bind(sockfd, (struct sockaddr *) &server_addr, sizeof(server_addr)) == SOCKET_ERROR ) {
+            log_it( L_ERROR, "Console Server: can't bind socket, err %X", errno );
+            closesocket( sockfd );
+            return -1;
+        }
     }
+
     // turn on reception of connections
-    if(listen(sockfd, 5) == SOCKET_ERROR)
+    if( listen(sockfd, MAX_CONSOLE_CLIENTS) == SOCKET_ERROR )
         return -1;
-    // create thread for waiting of clients
-    pthread_t threadId;
-    if(pthread_create(&threadId, NULL, thread_main_func, (void*) (intptr_t) sockfd) != 0) {
-        closesocket(sockfd);
+
+    if( pthread_create(&threadId, NULL, thread_main_func, (void*) (intptr_t) sockfd) != 0 ) {
+        closesocket( sockfd );
         return -1;
     }
+
     // in order to thread not remain in state "dead" after completion
-    pthread_detach(threadId);
+    pthread_detach( threadId );
     server_sockfd = sockfd;
+
     return 0;
 }
 
diff --git a/dap_chain_node_cli.h b/dap_chain_node_cli.h
index 327819df15..5823386904 100644
--- a/dap_chain_node_cli.h
+++ b/dap_chain_node_cli.h
@@ -28,7 +28,9 @@
 #include "dap_common.h"
 #include "dap_config.h"
 #include "uthash.h"
+
 #define UNIX_SOCKET_FILE "/opt/kelvin-node/var/run/node_cli.sock"
+
 //#define UNIX_SOCKET_FILE "/var/run/node_cli.sock"
 
 typedef int cmdfunc_t(int argc, char ** argv, char **str_reply);
diff --git a/dap_chain_node_cli_cmd.c b/dap_chain_node_cli_cmd.c
index 7554c78739..2b8205f0ee 100644
--- a/dap_chain_node_cli_cmd.c
+++ b/dap_chain_node_cli_cmd.c
@@ -23,20 +23,35 @@
  along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <sys/types.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-
+#include <stdlib.h>
 #include <stdio.h>
+#include <time.h>
 #include <stdlib.h>
+#include <stddef.h>
+#include <stdint.h>
 #include <string.h>
 #include <stdbool.h>
 #include <errno.h>
 #include <assert.h>
-#include <time.h>
 #include <ctype.h>
 #include <dirent.h>
 
+#ifdef WIN32
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0600
+#include <winsock2.h>
+#include <windows.h>
+#include <mswsock.h>
+#include <ws2tcpip.h>
+#include <io.h>
+#include <wepoll.h>
+#include <pthread.h>
+#else
+#include <sys/types.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#endif
+
 #include "iputils/iputils.h"
 
 #include "uthash.h"
@@ -920,6 +935,7 @@ int com_node(int a_argc, char ** a_argv, char **a_str_reply)
  */
 int com_traceroute(int argc, char** argv, char **str_reply)
 {
+#ifndef _WIN32
     const char *addr = NULL;
     int hops = 0, time_usec = 0;
     if(argc > 1)
@@ -987,6 +1003,8 @@ int com_traceroute(int argc, char** argv, char **str_reply)
         }
     }
     return res;
+#endif
+return 0;
 }
 
 /**
@@ -996,6 +1014,7 @@ int com_traceroute(int argc, char** argv, char **str_reply)
  */
 int com_tracepath(int argc, char** argv, char **str_reply)
 {
+#ifndef _WIN32
     const char *addr = NULL;
     int hops = 0, time_usec = 0;
     if(argc > 1)
@@ -1058,6 +1077,8 @@ int com_tracepath(int argc, char** argv, char **str_reply)
         }
     }
     return res;
+#endif
+  return 0;
 }
 
 /**
@@ -1067,6 +1088,8 @@ int com_tracepath(int argc, char** argv, char **str_reply)
  */
 int com_ping(int argc, char** argv, char **str_reply)
 {
+#ifndef _WIN32
+
     int n = 4;
     if(argc < 2) {
         dap_chain_node_cli_set_reply_text(str_reply, "host not specified");
@@ -1116,6 +1139,8 @@ int com_ping(int argc, char** argv, char **str_reply)
         }
     }
     return res;
+#endif
+return 0;
 }
 
 /**
@@ -1796,7 +1821,7 @@ int com_token_decl(int argc, char ** argv, char ** str_reply)
     // Create new datum token
     dap_chain_datum_token_t * l_datum_token = DAP_NEW_Z_SIZE(dap_chain_datum_token_t, sizeof(l_datum_token->header));
     l_datum_token->header.version = 1; // Current version
-    snprintf(l_datum_token->header.ticker, sizeof(l_datum_token->header.ticker), "%s", l_ticker);
+    dap_snprintf(l_datum_token->header.ticker, sizeof(l_datum_token->header.ticker), "%s", l_ticker);
     l_datum_token->header.total_supply = l_total_supply;
     l_datum_token->header.signs_total = l_signs_total;
     l_datum_token->header.signs_valid = l_signs_emission;
diff --git a/dap_chain_node_client.c b/dap_chain_node_client.c
index 25dce5bc72..ec4641f16d 100644
--- a/dap_chain_node_client.c
+++ b/dap_chain_node_client.c
@@ -19,13 +19,27 @@
  along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <stdint.h>
 #include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <errno.h>
-#include <glib.h>
+#include <stdio.h>
 #include <time.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <errno.h>
+#include <assert.h>
+#include <string.h>
+
+#ifdef WIN32
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0600
+#include <winsock2.h>
+#include <windows.h>
+#include <mswsock.h>
+#include <ws2tcpip.h>
+#include <io.h>
+#include <wepoll.h>
+#include <pthread.h>
+#endif
 
 #include "dap_common.h"
 #include "dap_client.h"
@@ -174,7 +188,7 @@ static void s_ch_chain_callback_notify_packet_in(dap_stream_ch_chain_t* a_ch_cha
         case DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_ERROR:
             pthread_mutex_lock(&l_node_client->wait_mutex);
             l_node_client->state = NODE_CLIENT_STATE_ERROR ;
-            snprintf(l_node_client->last_error,sizeof (l_node_client->last_error),
+            dap_snprintf(l_node_client->last_error,sizeof (l_node_client->last_error),
                      "%s", (char*) a_pkt->data );
             log_it(L_WARNING,"Received packet DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_ERROR with error \"%s\"",
                    l_node_client->last_error);
diff --git a/dap_chain_node_remote.c b/dap_chain_node_remote.c
index be11927275..515d1123b8 100644
--- a/dap_chain_node_remote.c
+++ b/dap_chain_node_remote.c
@@ -19,11 +19,25 @@
  along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <stdint.h>
 #include <stdlib.h>
-#include <string.h>
+#include <stdio.h>
+#include <time.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdint.h>
 #include <pthread.h>
 
+#ifdef WIN32
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0600
+#include <winsock2.h>
+#include <windows.h>
+#include <mswsock.h>
+#include <ws2tcpip.h>
+#include <io.h>
+#include <wepoll.h>
+#endif
+
 #include "uthash.h"
 #include "dap_common.h"
 #include "dap_chain_node_remote.h"
-- 
GitLab