diff --git a/dap-sdk/core/include/dap_common.h b/dap-sdk/core/include/dap_common.h
index 9452a02cbed7a7c64a2559f3f8abb8eceb0311cf..874a5dc568b5c008beefcfcfbeeeb7d9e6c5a460 100755
--- a/dap-sdk/core/include/dap_common.h
+++ b/dap-sdk/core/include/dap_common.h
@@ -40,6 +40,19 @@
 
 typedef uint8_t byte_t;
 
+// Stuffs an integer into a pointer type
+#define DAP_INT_TO_POINTER(i) ((void*) (long) (i))
+// Extracts an integer from a pointer
+#define DAP_POINTER_TO_INT(p) ((int)  (long) (p))
+// Stuffs an unsigned integer into a pointer type
+#define DAP_UINT_TO_POINTER(u) ((void*) (unsigned long) (u))
+// Extracts an unsigned integer from a pointer
+#define DAP_POINTER_TO_UINT(p) ((unsigned int) (unsigned long) (p))
+// Stuffs a size_t into a pointer type
+#define DAP_SIZE_TO_POINTER(s) ((void*) (size_t) (s))
+// Extracts a size_t from a pointer
+#define DAP_POINTER_TO_SIZE(p) ((size_t) (p))
+
 #if defined(__GNUC__) ||defined (__clang__)
   #define DAP_ALIGN_PACKED  __attribute__((aligned(1),packed))
 #else
diff --git a/dap-sdk/net/core/dap_timerfd.c b/dap-sdk/net/core/dap_timerfd.c
new file mode 100644
index 0000000000000000000000000000000000000000..dec3016a0dd01ae237383a6e8b0728d912cdf44f
--- /dev/null
+++ b/dap-sdk/net/core/dap_timerfd.c
@@ -0,0 +1,152 @@
+/*
+ * Authors:
+ * Alexander Lysikov <alexander.lysikov@demlabs.net>
+ * DeM Labs Inc.   https://demlabs.net
+ * Kelvin Project https://github.com/kelvinblockchain
+ * Copyright  (c) 2020
+ * All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+ DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ DAP is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ 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 <stdint.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/timerfd.h>
+#include <inttypes.h>
+
+#include "dap_common.h"
+#include "dap_events_socket.h"
+#include "dap_timerfd.h"
+
+#define LOG_TAG "dap_timerfd"
+
+void callback_timerfd_read(struct dap_events_socket *a_event_sock, void * arg)
+{
+    uint64_t l_ptiu64;
+    size_t l_read_ret;
+    do {
+        l_read_ret = dap_events_socket_read(a_event_sock, &l_ptiu64, sizeof(l_ptiu64));
+
+        if(l_read_ret > 0) {
+            dap_timerfd_t *l_timerfd = a_event_sock->_inheritor;
+            //printf("\nread() returned %d, %d\n", l_ptiu64, l_read_ret);
+            struct itimerspec l_ts;
+            // first expiration in 0 seconds after times start
+            l_ts.it_interval.tv_sec = 0;
+            l_ts.it_interval.tv_nsec = 0;
+            // timeout for timer
+            l_ts.it_value.tv_sec = l_timerfd->timeout_ms / 1000;
+            l_ts.it_value.tv_nsec = (l_timerfd->timeout_ms % 1000) * 1000000;
+            if(timerfd_settime(l_timerfd->tfd, 0, &l_ts, NULL) < 0) {
+                log_it(L_WARNING, "callback_timerfd_read() failed: timerfd_settime() errno=%d\n", errno);
+            }
+            // run user's callback
+            if(l_timerfd->callback)
+                l_timerfd->callback(l_timerfd->callback_arg);
+        }
+    } while(l_read_ret > 0);
+    dap_events_socket_set_readable(a_event_sock, true);
+}
+
+/**
+ * @brief dap_events_socket_init Init clients module
+ * @return Zero if ok others if no
+ */
+int dap_timerfd_init()
+{
+    log_it(L_NOTICE, "Initialized timerfd");
+    return 0;
+}
+
+/**
+ * @brief dap_timerfd_start
+ * @param a_timeout_ms
+ * @param a_callback
+ * @return new allocated dap_timerfd_t structure or NULL if error
+ */
+dap_timerfd_t* dap_timerfd_start(uint64_t a_timeout_ms, dap_timerfd_callback_t *a_callback, void *a_callback_arg)
+{
+    struct itimerspec l_ts;
+    int l_tfd = timerfd_create(CLOCK_MONOTONIC, 0);
+    if(l_tfd == -1) {
+        log_it(L_WARNING, "dap_timerfd_start() failed: timerfd_create() errno=%d\n", errno);
+        return NULL;
+    }
+    // first expiration in 0 seconds after times start
+    l_ts.it_interval.tv_sec = 0;
+    l_ts.it_interval.tv_nsec = 0;
+    // timeout for timer
+    l_ts.it_value.tv_sec = a_timeout_ms / 1000;
+    l_ts.it_value.tv_nsec = (a_timeout_ms % 1000) * 1000000;
+    if(timerfd_settime(l_tfd, 0, &l_ts, NULL) < 0) {
+        log_it(L_WARNING, "dap_timerfd_start() failed: timerfd_settime() errno=%d\n", errno);
+        close(l_tfd);
+        return NULL;
+    }
+
+    // create dap_timerfd_t structure
+    dap_timerfd_t *l_timerfd = DAP_NEW(dap_timerfd_t);
+
+    // create events_socket for timer file descriptor
+    static dap_events_socket_callbacks_t l_s_callbacks = {
+        .read_callback = callback_timerfd_read,
+        .write_callback = NULL,
+        .error_callback = NULL,
+        .delete_callback = NULL
+    };
+    dap_events_socket_t * l_events_socket = dap_events_socket_wrap_no_add(NULL, l_tfd, &l_s_callbacks);
+    l_events_socket->type = DESCRIPTOR_TYPE_FILE;
+    dap_events_socket_create_after(l_events_socket);
+    // pass l_timerfd to events_socket
+    l_events_socket->_inheritor = l_timerfd;
+
+    // fill out dap_timerfd_t structure
+    l_timerfd->timeout_ms = a_timeout_ms;
+    l_timerfd->tfd = l_tfd;
+    l_timerfd->events_socket = l_events_socket;
+    l_timerfd->callback = a_callback;
+    l_timerfd->callback_arg = a_callback_arg;
+    return l_timerfd;
+}
+
+/**
+ * @brief dap_timerfd_stop
+ * @param a_tfd
+ * @param a_callback
+ * @return 0 or <0 if error
+ */
+int dap_timerfd_delete(dap_timerfd_t *l_timerfd)
+{
+    if(!l_timerfd || l_timerfd->tfd < 1 || !l_timerfd->events_socket) {
+        return -1;
+    }
+
+    if(close(l_timerfd->tfd) == -1) {
+        log_it(L_WARNING, "dap_timerfd_stop() failed to close timerfd: errno=%d\n", errno);
+        return -2;
+    }
+
+    dap_events_socket_kill_socket(l_timerfd->events_socket);
+    l_timerfd->events_socket = NULL;
+    DAP_DELETE(l_timerfd);
+    return 0;
+}
+
diff --git a/dap-sdk/net/core/include/dap_timerfd.h b/dap-sdk/net/core/include/dap_timerfd.h
new file mode 100644
index 0000000000000000000000000000000000000000..a658606e8395a69668ae11d1fa430c35e5e011dd
--- /dev/null
+++ b/dap-sdk/net/core/include/dap_timerfd.h
@@ -0,0 +1,51 @@
+/*
+ * Authors:
+ * Alexander Lysikov <alexander.lysikov@demlabs.net>
+ * DeM Labs Inc.   https://demlabs.net
+ * Kelvin Project https://github.com/kelvinblockchain
+ * Copyright  (c) 2020
+ * All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+ DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ DAP is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ 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 <stdint.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/timerfd.h>
+#include <inttypes.h>
+
+#include "dap_common.h"
+#include "dap_events_socket.h"
+
+typedef void (*dap_timerfd_callback_t)(void * arg); // Callback for timer
+
+typedef struct dap_timerfd {
+    uint64_t timeout_ms;
+    int tfd; //timer file descriptor
+    dap_events_socket_t *events_socket;
+    dap_timerfd_callback_t callback;
+    void *callback_arg;
+} dap_timerfd_t;
+
+int dap_timerfd_init();
+dap_timerfd_t* dap_timerfd_start(uint64_t a_timeout_ms, dap_timerfd_callback_t *a_callback, void *callback_arg);
+int dap_timerfd_delete(dap_timerfd_t *l_timerfd);
+
diff --git a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c
index 694be366df353fc5786cacaa283489c6e94aff2c..ddd9ad790d4ae25e45da02c3385ab112e9d4dc33 100644
--- a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c
+++ b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c
@@ -21,7 +21,11 @@ GNU General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/licenses/>.
 */
+
+#include <sys/time.h>
 #include "dap_common.h"
+#include "dap_hash.h"
+#include "rand/dap_rand.h"
 
 #include "dap_chain.h"
 #include "dap_chain_datum_tx.h"
@@ -42,17 +46,16 @@ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/lic
 #include "dap_stream_ch_pkt.h"
 #include "dap_stream_ch_chain_net_srv.h"
 #include "dap_stream_ch_chain_net_srv_pkt.h"
-
 #include "dap_stream_ch_proc.h"
+#include "dap_stream_ch_chain_net_srv.h"
 
 #define LOG_TAG "dap_stream_ch_chain_net_srv"
 
-typedef struct dap_stream_ch_chain_net_srv {
-    pthread_mutex_t mutex;
-    dap_chain_net_srv_uid_t srv_uid;
-} dap_stream_ch_chain_net_srv_t;
 
-#define DAP_STREAM_CH_CHAIN_NET_SRV(a) ((dap_stream_ch_chain_net_srv_t *) ((a)->internal) )
+uint8_t dap_stream_ch_chain_net_srv_get_id()
+{
+    return 'R';
+}
 
 static void s_stream_ch_new(dap_stream_ch_t* ch , void* arg);
 static void s_stream_ch_delete(dap_stream_ch_t* ch , void* arg);
@@ -146,6 +149,61 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg)
 
     if(l_ch_pkt ) {
         switch (l_ch_pkt->hdr.type) {
+            // for send test data
+            case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_CHECK_REQUEST:{
+                int l_err_code = 0;
+                dap_stream_ch_chain_net_srv_pkt_test_t *l_request = (dap_stream_ch_chain_net_srv_pkt_request_t*) l_ch_pkt->data;
+                size_t l_request_size = l_request->data_size + sizeof(dap_stream_ch_chain_net_srv_pkt_test_t);
+                if(l_ch_pkt->hdr.size != l_request_size) {
+                    log_it(L_WARNING, "Wrong request size, less or more than required");
+                    break;
+                }
+
+                gettimeofday(&l_request->recv_time2, NULL);
+                //printf("\n%lu.%06lu \n", (unsigned long) l_request->recv_time2.tv_sec, (unsigned long) l_request->recv_time2.tv_usec);
+                dap_chain_hash_fast_t l_data_hash;
+                dap_hash_fast(l_request->data, l_request->data_size, &l_data_hash);
+                if(l_request->data_size>0 && !dap_hash_fast_compare(&l_data_hash, &(l_request->data_hash))){
+                    l_err_code+=2;
+                }
+
+                // create data to send back
+                dap_stream_ch_chain_net_srv_pkt_test_t *l_request_out = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_test_t, sizeof(dap_stream_ch_chain_net_srv_pkt_test_t) + l_request->data_size_recv);
+                // copy info from recv message
+                memcpy(l_request_out,l_request, sizeof(dap_stream_ch_chain_net_srv_pkt_test_t));
+                l_request_out->data_size = l_request->data_size_recv;
+                randombytes(l_request_out->data, l_request_out->data_size);
+                l_request_out->err_code = l_err_code;
+                dap_hash_fast(l_request_out->data, l_request_out->data_size, &l_request_out->data_hash);
+                memcpy(l_request_out->ip_send, a_ch->stream->conn->s_ip, sizeof(l_request_out->ip_send));
+                gettimeofday(&l_request_out->send_time2, NULL);
+
+                // send response
+                if(dap_stream_ch_pkt_write(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_CHECK_RESPONSE, l_request_out, l_request_out->data_size + sizeof(dap_stream_ch_chain_net_srv_pkt_test_t))) {
+                        dap_stream_ch_set_ready_to_write(a_ch, true);
+                    }
+                DAP_DELETE(l_request_out);
+
+                }
+            break;
+            // for receive test data.
+            case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_CHECK_RESPONSE: {
+                dap_stream_ch_chain_net_srv_pkt_test_t *l_request = (dap_stream_ch_chain_net_srv_pkt_request_t *) l_ch_pkt->data;
+                size_t l_request_size = l_request->data_size + sizeof(dap_stream_ch_chain_net_srv_pkt_test_t);
+                if(l_ch_pkt->hdr.size != l_request_size) {
+                    log_it(L_WARNING, "Wrong request size, less or more than required");
+                    break;
+                }
+                gettimeofday(&l_request->recv_time1, NULL);
+                dap_chain_hash_fast_t l_data_hash;
+                dap_hash_fast(l_request->data, l_request->data_size, &l_data_hash);
+                if(!dap_hash_fast_compare(&l_data_hash, &(l_request->data_hash))) {
+                    l_request->err_code += 4;
+                }
+                dap_stream_ch_set_ready_to_write(a_ch, false);
+            }
+            break;
+
         	// only for server
             case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_REQUEST:{
                 if (l_ch_pkt->hdr.size < sizeof(dap_stream_ch_chain_net_srv_pkt_request_hdr_t) ){
@@ -577,6 +635,8 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg)
             } break;
             default: log_it( L_WARNING, "Unknown packet type 0x%02X", l_ch_pkt->hdr.type);
         }
+        if(l_ch_chain_net_srv->notify_callback)
+            l_ch_chain_net_srv->notify_callback(l_ch_chain_net_srv, l_ch_pkt->hdr.type, l_ch_pkt, l_ch_chain_net_srv->notify_callback_arg);
     }
 
 }
diff --git a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.h b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.h
new file mode 100644
index 0000000000000000000000000000000000000000..f6b83f171919a1d99abfff45a5cfa156cb3a5380
--- /dev/null
+++ b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.h
@@ -0,0 +1,47 @@
+/*
+ * Authors:
+ * Alexander Lysikov <alexander.lysikov@demlabs.net>
+ * Cellframe       https://cellframe.net
+ * DeM Labs Inc.   https://demlabs.net
+ * Copyright  (c) 2020
+ * All rights reserved.
+
+ This file is part of CellFrame SDK the open source project
+
+ CellFrame SDK is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ CellFrame SDK is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <pthread.h>
+#include "dap_stream_ch.h"
+#include "dap_stream_ch_pkt.h"
+
+typedef struct dap_stream_ch_chain_net_srv dap_stream_ch_chain_net_srv_t;
+
+typedef void (*dap_stream_ch_chain_net_srv_callback_packet_t)(dap_stream_ch_chain_net_srv_t *, uint8_t,
+        dap_stream_ch_pkt_t *, void *);
+
+typedef struct dap_stream_ch_chain_net_srv {
+    pthread_mutex_t mutex;
+    dap_chain_net_srv_uid_t srv_uid;
+    dap_stream_ch_chain_net_srv_callback_packet_t notify_callback;
+    void *notify_callback_arg;
+} dap_stream_ch_chain_net_srv_t;
+
+#define DAP_STREAM_CH_CHAIN_NET_SRV(a) ((dap_stream_ch_chain_net_srv_t *) ((a)->internal) )
+
+void dap_stream_ch_chain_net_srv_set_srv_uid(dap_stream_ch_t* a_ch, dap_chain_net_srv_uid_t a_srv_uid);
+uint8_t dap_stream_ch_chain_net_srv_get_id();
+
diff --git a/modules/net/CMakeLists.txt b/modules/net/CMakeLists.txt
index 9c3c877a0e8c713e8567edfa7f758ec57af7ceaf..e5d055725660d5a26b7aa656d5037c7616204d48 100644
--- a/modules/net/CMakeLists.txt
+++ b/modules/net/CMakeLists.txt
@@ -39,12 +39,12 @@ endif()
 add_library(${PROJECT_NAME} STATIC ${DAP_CHAIN_NET_SRCS} ${DAP_CHAIN_NET_HEADERS} ${IPUTILS_SRCS} ${IPUTILS_HEADERS})
 
 if(WIN32)
-  target_link_libraries(dap_chain_net dap_core dap_crypto dap_client dap_stream_ch_chain dap_stream_ch_chain_net dap_chain dap_chain_crypto dap_chain_wallet dap_chain_net_srv
+  target_link_libraries(dap_chain_net dap_core dap_crypto dap_client dap_stream_ch_chain dap_stream_ch_chain_net dap_stream_ch_chain_net_srv dap_chain dap_chain_crypto dap_chain_wallet dap_chain_net_srv
                             dap_chain_mempool dap_chain_global_db dap_chain_net_srv_stake)
 endif()
 
 if(UNIX)
-    target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_client dap_stream_ch_chain dap_stream_ch_chain_net dap_chain
+    target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_client dap_stream_ch_chain dap_stream_ch_chain_net dap_stream_ch_chain_net_srv dap_chain
       dap_chain_wallet dap_chain_net_srv dap_chain_mempool dap_chain_global_db dap_chain_net_srv_stake
       resolv
       )
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index f208c1eaa5774bc90f506f7d6e2d57ef8738f44b..3df5696454e679022a615867a307813dfea5a1a6 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -57,6 +57,7 @@
 #include "dap_string.h"
 #include "dap_strfuncs.h"
 #include "dap_file_utils.h"
+#include "dap_enc_base58.h"
 #include "dap_config.h"
 #include "dap_hash.h"
 #include "dap_cert.h"
diff --git a/modules/net/dap_chain_node_client.c b/modules/net/dap_chain_node_client.c
index 1c3fe94d75e7944768ed291173f5714867dc825a..3c21deb1aeeac66b011c7baa30676b1fe13067ca 100644
--- a/modules/net/dap_chain_node_client.c
+++ b/modules/net/dap_chain_node_client.c
@@ -29,6 +29,7 @@
 #include <errno.h>
 #include <assert.h>
 #include <string.h>
+#include <json-c/json.h>
 
 #ifdef WIN32
 #include <winsock2.h>
@@ -48,11 +49,13 @@
 #include "dap_client_pvt.h"
 #include "dap_chain_global_db_remote.h"
 #include "dap_chain_global_db_hist.h"
+#include "dap_chain_net_srv_common.h"
 #include "dap_stream_ch_pkt.h"
 #include "dap_stream_ch_chain.h"
 #include "dap_stream_ch_chain_pkt.h"
 #include "dap_stream_ch_chain_net.h"
 #include "dap_stream_ch_chain_net_pkt.h"
+#include "dap_stream_ch_chain_net_srv.h"
 #include "dap_stream_pkt.h"
 
 //#include "dap_chain_common.h"
@@ -248,6 +251,7 @@ static void s_ch_chain_callback_notify_packet_in2(dap_stream_ch_chain_net_t* a_c
     }
 }
 
+
 /**
  * @brief s_ch_chain_callback_notify_packet_in - for dap_stream_ch_chain
  * @param a_ch_chain
@@ -410,6 +414,8 @@ static void s_ch_chain_callback_notify_packet_in(dap_stream_ch_chain_t* a_ch_cha
     }
 }
 
+
+
 /**
  * @brief s_ch_chain_callback_notify_packet_in
  * @param a_ch_chain
@@ -445,6 +451,86 @@ static void s_ch_chain_callback_notify_packet_out(dap_stream_ch_chain_t* a_ch_ch
     }
 }
 
+static int save_stat_to_database(dap_stream_ch_chain_net_srv_pkt_test_t *a_request, dap_chain_node_client_t * a_node_client)
+{
+    int l_ret = 0;
+    if(!a_request)
+        return -1;
+    long l_t1_ms = (long) a_request->send_time1.tv_sec * 1000 + a_request->send_time1.tv_usec / 1000;
+    long l_t2_ms = (long) a_request->recv_time1.tv_sec * 1000 + a_request->recv_time1.tv_usec / 1000;
+    struct json_object *jobj = json_object_new_object();
+    time_t l_cur_t = time(NULL);
+    char buf[1024];
+    dap_time_to_str_rfc822( buf, sizeof(buf), l_cur_t );
+    json_object_object_add(jobj, "time_save", json_object_new_int64(l_cur_t));
+    json_object_object_add(jobj, "time_save_str", json_object_new_string(buf));
+    json_object_object_add(jobj, "time_connect", json_object_new_int(a_request->time_connect_ms));
+    json_object_object_add(jobj, "time_transmit", json_object_new_int(l_t2_ms-l_t1_ms));
+    json_object_object_add(jobj, "ip_send", json_object_new_string(a_request->ip_send));
+    json_object_object_add(jobj, "ip_recv", json_object_new_string(a_request->ip_recv));
+    json_object_object_add(jobj, "time_len_send", json_object_new_int(a_request->data_size_send));
+    json_object_object_add(jobj, "time_len_recv", json_object_new_int(a_request->data_size_recv));
+    json_object_object_add(jobj, "err_code", json_object_new_int(a_request->err_code));
+    const char* json_str = json_object_to_json_string(jobj);
+    // save statistics
+    char *l_group = NULL;
+    dap_chain_net_t * l_net = dap_chain_net_by_id(a_request->net_id);
+    if(l_net) {
+        l_group = dap_strdup_printf("%s.orders-test-stat", l_net->pub.gdb_groups_prefix);
+    }
+    if(l_group) {
+        dap_store_obj_t *l_obj = dap_chain_global_db_get_last(l_group);
+        int64_t l_key = 0;
+        if(l_obj) {
+            l_key = strtoll(l_obj->key, NULL, 16);
+        }
+        char *l_key_str = dap_strdup_printf("%06x", ++l_key);
+        if(!dap_chain_global_db_gr_set(dap_strdup(l_key_str), (uint8_t *) json_str, strlen(json_str) + 1, l_group)) {
+            l_ret = -1;
+        }
+        DAP_DELETE(l_key_str);
+        DAP_DELETE(l_group);
+    }
+    else
+        l_ret = -2;
+    json_object_put(jobj);
+    return l_ret;
+}
+/**
+ * @brief s_ch_chain_callback_notify_packet_R - Callback for channel 'R'
+ * @param a_ch_chain
+ * @param a_pkt_type
+ * @param a_pkt
+ * @param a_arg
+ */
+static void s_ch_chain_callback_notify_packet_R(dap_stream_ch_chain_net_srv_t* a_ch_chain, uint8_t a_pkt_type, dap_stream_ch_pkt_t *a_pkt, void * a_arg)
+{
+    dap_chain_node_client_t * l_node_client = (dap_chain_node_client_t *) a_arg;
+    switch (a_pkt_type) {
+    // get new generated current node address
+    case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_CHECK_RESPONSE: {
+            dap_stream_ch_chain_net_srv_pkt_test_t *l_request = (dap_stream_ch_chain_net_srv_pkt_request_t *) a_pkt->data;
+            size_t l_request_size = l_request->data_size + sizeof(dap_stream_ch_chain_net_srv_pkt_test_t);
+            if(a_pkt->hdr.size != l_request_size) {
+                log_it(L_WARNING, "Wrong request size, less or more than required");
+                break;
+            }
+            // todo to write result to database
+            save_stat_to_database(l_request, l_node_client);
+            //...
+            pthread_mutex_lock(&l_node_client->wait_mutex);
+            l_node_client->state = NODE_CLIENT_STATE_CHECKED;
+            pthread_mutex_unlock(&l_node_client->wait_mutex);
+#ifndef _WIN32
+            pthread_cond_signal(&l_node_client->wait_cond);
+#else
+            SetEvent( l_node_client->wait_cond );
+#endif
+            break;
+        }
+    }
+}
+
 /**
  * Create connection to server
  *
@@ -658,17 +744,25 @@ int dap_chain_node_client_set_callbacks(dap_client_t *a_client, uint8_t a_ch_id)
         if(l_client_internal)
             l_ch = dap_client_get_stream_ch(a_client, a_ch_id);
         if(l_ch) {
+            // C
             if(a_ch_id == dap_stream_ch_chain_get_id()) {
                 dap_stream_ch_chain_t * l_ch_chain = DAP_STREAM_CH_CHAIN(l_ch);
                 l_ch_chain->callback_notify_packet_out = s_ch_chain_callback_notify_packet_out;
                 l_ch_chain->callback_notify_packet_in = s_ch_chain_callback_notify_packet_in;
                 l_ch_chain->callback_notify_arg = l_node_client;
             }
+            // N
             if(a_ch_id == dap_stream_ch_chain_net_get_id()) {
                 dap_stream_ch_chain_net_t *l_ch_chain = DAP_STREAM_CH_CHAIN_NET(l_ch);
                 l_ch_chain->notify_callback = s_ch_chain_callback_notify_packet_in2;
                 l_ch_chain->notify_callback_arg = l_node_client;
             }
+            // R
+            if(a_ch_id == dap_stream_ch_chain_net_srv_get_id()) {
+                dap_stream_ch_chain_net_srv_t * l_ch_chain = DAP_STREAM_CH_CHAIN_NET_SRV(l_ch);
+                l_ch_chain->notify_callback = s_ch_chain_callback_notify_packet_R;
+                l_ch_chain->notify_callback_arg = l_node_client;
+            }
             l_ret = 0;
         } else {
         }
diff --git a/modules/net/include/dap_chain_node_client.h b/modules/net/include/dap_chain_node_client.h
index 4a5eb2e307768a133a46050a280d871b4bff22e2..de35fd3d8adb6f41621de7678c5203c57bf6d149 100644
--- a/modules/net/include/dap_chain_node_client.h
+++ b/modules/net/include/dap_chain_node_client.h
@@ -44,6 +44,7 @@ typedef enum dap_chain_node_client_state {
     NODE_CLIENT_STATE_SYNC_GDB = 101,
     NODE_CLIENT_STATE_SYNC_CHAINS = 102,
     NODE_CLIENT_STATE_SYNCED = 103,
+    NODE_CLIENT_STATE_CHECKED = 104,
 } dap_chain_node_client_state_t;
 
 typedef struct dap_chain_node_client dap_chain_node_client_t;
diff --git a/modules/net/srv/dap_chain_net_srv_common.c b/modules/net/srv/dap_chain_net_srv_common.c
index 23618345a63e6462533f0fe4356e49009212b198..601f847236016b51f787520f9edf1d238714a40f 100644
--- a/modules/net/srv/dap_chain_net_srv_common.c
+++ b/modules/net/srv/dap_chain_net_srv_common.c
@@ -46,7 +46,4 @@
 #include "dap_stream.h"
 #include "dap_chain_net_srv_common.h"
 
-uint8_t dap_stream_ch_chain_net_srv_get_id()
-{
-    return 'R';
-}
+
diff --git a/modules/net/srv/dap_chain_net_srv_order.c b/modules/net/srv/dap_chain_net_srv_order.c
index 9d536c535ac465ede1ecfc1315a0b0690169dc5c..e3df6bfad4021dbb823a9a984b305cd960c78f2c 100644
--- a/modules/net/srv/dap_chain_net_srv_order.c
+++ b/modules/net/srv/dap_chain_net_srv_order.c
@@ -489,6 +489,19 @@ void dap_chain_net_srv_order_dump_to_string(dap_chain_net_srv_order_t *a_order,d
             dap_string_append_printf(a_str_out, "  ext:              0x%s\n", l_ext_out);
         else
             dap_string_append_printf(a_str_out, "  ext:              0x0\n");
+        // order state
+/*        {
+            int l_order_state = get_order_state(a_order->node_addr);
+            // if order is not tested
+            if(l_order_state == -1)
+                dap_string_append_printf(a_str_out, "        \"State\":\"unknown\"\n");
+            // if order off-line
+            else if(l_order_state == 1)
+                dap_string_append_printf(a_str_out, "        \"State\":\"available\"\n");
+            // if order on-line
+            else
+                dap_string_append_printf(a_str_out, "        \"State\":\"not available\"\n");
+        }*/
         DAP_DELETE(l_hash_str);
         DAP_DELETE(l_ext_out);
     }
diff --git a/modules/net/srv/include/dap_chain_net_srv_common.h b/modules/net/srv/include/dap_chain_net_srv_common.h
index 673e65959d98c908713d00f39ad2f76561c934b6..d45ace6791a839ce7019b8b642c7de519b4fc737 100755
--- a/modules/net/srv/include/dap_chain_net_srv_common.h
+++ b/modules/net/srv/include/dap_chain_net_srv_common.h
@@ -98,6 +98,9 @@ typedef struct dap_chain_net_srv_price
 #define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_DATA                          0x30
 #define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_SUCCESS              0xf0
 #define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR                0xff
+// for connection testing
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_CHECK_REQUEST                 0x40
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_CHECK_RESPONSE                0x41
 
 #define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_UNDEFINED                  0x00000000
 #define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_SERVICE_NOT_FOUND          0x00000100
@@ -163,7 +166,25 @@ typedef struct dap_stream_ch_chain_net_srv_pkt_error{
     uint32_t code; // error code
 } DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_error_t;
 
-
+// data packet for connectiont test
+typedef struct dap_stream_ch_chain_net_srv_pkt_test{
+    uint32_t usage_id;
+    dap_chain_net_id_t net_id;
+    dap_chain_net_srv_uid_t srv_uid;
+    int32_t  time_connect_ms;
+    struct timeval recv_time1;
+    struct timeval recv_time2;
+    struct timeval send_time1;
+    struct timeval send_time2;
+    char ip_send[16];
+    char ip_recv[16];
+    int32_t err_code;
+    size_t data_size_send;
+    size_t data_size_recv;
+    size_t data_size;
+    dap_chain_hash_fast_t data_hash;
+    uint8_t data[];
+} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_test_t;
 
 
 DAP_STATIC_INLINE const char * dap_chain_net_srv_price_unit_uid_to_str( dap_chain_net_srv_price_unit_uid_t a_uid )
diff --git a/modules/service/vpn/dap_chain_net_srv_vpn_cmd.c b/modules/service/vpn/dap_chain_net_srv_vpn_cmd.c
index 01a18e9f0d56708000f00ff5ed3d7baefd032d39..ce9f46417292427b0b42e8359cd9dbe1e8dddc0f 100644
--- a/modules/service/vpn/dap_chain_net_srv_vpn_cmd.c
+++ b/modules/service/vpn/dap_chain_net_srv_vpn_cmd.c
@@ -12,9 +12,19 @@ int com_vpn_client(int a_argc, char ** a_argv, void *arg_func, char **a_str_repl
 {
 #ifndef _WIN32
     enum {
-        CMD_NONE, CMD_INIT, CMD_START, CMD_STOP, CMD_STATUS
+        CMD_NONE, CMD_INIT, CMD_START, CMD_STOP, CMD_STATUS, CMD_CHECK, CMD_CHECK_RESULT
     };
     int l_arg_index = 1;
+
+    const char * l_hash_out_type = NULL;
+    dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-H", &l_hash_out_type);
+    if(!l_hash_out_type)
+        l_hash_out_type = "base58";
+    if(dap_strcmp(l_hash_out_type,"hex") && dap_strcmp(l_hash_out_type,"base58")) {
+        dap_chain_node_cli_set_reply_text(a_str_reply, "invalid parameter -H, valid values: -H <hex | base58>");
+        return -1;
+    }
+
     // find net
     dap_chain_net_t *l_net = NULL;
     if(dap_chain_node_cli_cmd_values_parse_net_chain(&l_arg_index, a_argc, a_argv, a_str_reply, NULL, &l_net) < 0)
@@ -33,6 +43,12 @@ int com_vpn_client(int a_argc, char ** a_argv, void *arg_func, char **a_str_repl
     else if(dap_chain_node_cli_find_option_val(a_argv, l_arg_index, min(a_argc, l_arg_index + 1), "status", NULL)) {
         cmd_num = CMD_STATUS;
     }
+    else if(dap_chain_node_cli_find_option_val(a_argv, l_arg_index, min(a_argc, l_arg_index + 1), "check", NULL)) {
+        cmd_num = CMD_CHECK;
+        if(dap_chain_node_cli_find_option_val(a_argv, min(a_argc, l_arg_index + 1), min(a_argc, l_arg_index + 2), "result", NULL)) {
+                cmd_num = CMD_CHECK_RESULT;
+            }
+    }
     if(cmd_num == CMD_NONE) {
         if(!a_argv[1])
             dap_chain_node_cli_set_reply_text(a_str_reply, "invalid parameters");
@@ -43,6 +59,55 @@ int com_vpn_client(int a_argc, char ** a_argv, void *arg_func, char **a_str_repl
 
     switch (cmd_num)
     {
+    case CMD_CHECK_RESULT: {
+        char *l_str = dap_chain_net_vpn_client_check_result(l_net, l_hash_out_type);
+        dap_chain_node_cli_set_reply_text(a_str_reply, l_str);
+        DAP_DELETE(l_str);
+    }
+    break;
+    case CMD_CHECK: {
+        const char * l_str_addr = NULL; // for example, "192.168.100.93"
+        const char * l_str_port = NULL; // for example, "8079"
+        dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-addr", &l_str_addr);
+        if(!l_str_addr) {
+            dap_chain_node_cli_set_reply_text(a_str_reply,
+                    "VPN server address not defined, use -addr <vpn server ipv4 address> parameter");
+            break;
+        }
+        dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-port", &l_str_port);
+        int l_srv_port = (l_str_port) ? (int) strtoll(l_str_port, 0, 10) : 0;
+        if(!l_srv_port) {
+            dap_chain_node_cli_set_reply_text(a_str_reply,
+                    "VPN server port not defined, use -port <vpn server port>  parameter");
+            break;
+        }
+        size_t l_data_size_to_send = 10240;
+        size_t l_data_size_to_recv = 0;// no recv data, only send
+        // default timeout 10ms
+        int l_timeout_test_ms = dap_config_get_item_int32_default( g_config,"cdb", "servers_list_check_timeout", 20) * 1000;// read settings
+        // start node check
+        int l_res = dap_chain_net_vpn_client_check(l_net, l_str_addr, NULL, l_srv_port, l_data_size_to_send, l_data_size_to_recv, l_timeout_test_ms);
+        if(!l_res){
+            l_data_size_to_send = 0;// no send data, only recv
+            size_t l_data_size_to_recv = 10240;
+            int l_timeout_test_ms = -1;// default timeout
+            int l_res = dap_chain_net_vpn_client_check(l_net, l_str_addr, NULL, l_srv_port, l_data_size_to_send, l_data_size_to_recv, l_timeout_test_ms);
+        }
+        switch (l_res) {
+        case 0:
+            dap_chain_node_cli_set_reply_text(a_str_reply, "tested VPN server successfully");
+            break;
+        case -2:
+        case -3:
+            dap_chain_node_cli_set_reply_text(a_str_reply, "Can't connect to VPN server");
+            break;
+        default:
+            dap_chain_node_cli_set_reply_text(a_str_reply, "Can't recognize error code=%d", l_res);
+            break;
+        }
+        return l_res;
+    }
+        break;
     case CMD_INIT: {
             const char * l_str_token = NULL; // token name
             const char * l_str_value_datoshi = NULL;
diff --git a/modules/service/vpn/dap_chain_net_vpn_client.c b/modules/service/vpn/dap_chain_net_vpn_client.c
index ef7b2d77df63ed27bc32567ec122c3f7730ca794..24c919c9bb47247b1a97167966c23ec9824f55a6 100644
--- a/modules/service/vpn/dap_chain_net_vpn_client.c
+++ b/modules/service/vpn/dap_chain_net_vpn_client.c
@@ -38,8 +38,10 @@
 #include "dap_common.h"
 #include "dap_config.h"
 #include "dap_strfuncs.h"
+#include "rand/dap_rand.h"
 
 #include "dap_client.h"
+#include "dap_enc_base58.h"
 #include "dap_chain_node_client.h"
 
 #include "dap_stream_ch_proc.h"
@@ -47,6 +49,7 @@
 
 #include "dap_chain_common.h"
 #include "dap_chain_mempool.h"
+#include "dap_chain_node_cli.h"
 #include "dap_chain_net_srv_vpn.h"
 #include "dap_chain_net_srv_vpn_cdb.h" // for DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX
 #include "dap_chain_net_vpn_client.h"
@@ -56,6 +59,7 @@
 //#include "dap_stream_ch_chain_net_srv.h"
 #include "dap_chain_net_vpn_client_tun.h"
 #include "dap_chain_net_srv_vpn_cmd.h"
+#include "dap_chain_net_srv_vpn_cdb_server_list.h"
 //#include "dap_chain_net_vpn_client_data.h"
 
 /*
@@ -303,6 +307,167 @@ int dap_chain_net_vpn_client_get_wallet_info(dap_chain_net_t *a_net, char **a_wa
     return 0;
 }
 
+
+char *dap_chain_net_vpn_client_check_result(dap_chain_net_t *a_net, const char* a_hash_out_type)
+{
+
+
+    dap_chain_net_srv_order_t * l_orders = NULL;
+    size_t l_orders_num = 0;
+    dap_chain_net_srv_uid_t l_srv_uid = { { 0 } };
+    uint64_t l_price_min = 0, l_price_max = 0;
+    dap_chain_net_srv_price_unit_uid_t l_price_unit = { { 0 } };
+    dap_chain_net_srv_order_direction_t l_direction = SERV_DIR_UNDEFINED;
+    dap_string_t *l_string_ret = dap_string_new("");
+
+    if(dap_chain_net_srv_order_find_all_by(a_net, l_direction, l_srv_uid, l_price_unit, NULL, l_price_min, l_price_max, &l_orders, &l_orders_num) == 0){
+        size_t l_orders_size = 0;
+        for(size_t i = 0; i < l_orders_num; i++) {
+            dap_chain_net_srv_order_t *l_order = (dap_chain_net_srv_order_t *) (((byte_t*) l_orders) + l_orders_size);
+            //dap_chain_net_srv_order_dump_to_string(l_order, l_string_ret, l_hash_out_type);
+            dap_chain_hash_fast_t l_hash;
+            char *l_hash_str;
+            dap_hash_fast(l_order, dap_chain_net_srv_order_get_size(l_order), &l_hash);
+            if(!dap_strcmp(a_hash_out_type, "hex"))
+                l_hash_str = dap_chain_hash_fast_to_str_new(&l_hash);
+            else
+                l_hash_str = dap_enc_base58_encode_hash_to_str(&l_hash);
+            int l_state = get_order_state(l_order->node_addr);
+            const char *l_state_str;
+            switch (l_state)
+            {
+            case 0:
+                l_state_str = "Not available";
+                break;
+            case 1:
+                l_state_str = "Available";
+                break;
+            default:
+                l_state_str = "Unknown";
+            }
+            dap_string_append_printf(l_string_ret, "Order %s: State %s\n", l_hash_str, l_state_str);
+            DAP_DELETE(l_hash_str);
+            l_orders_size += dap_chain_net_srv_order_get_size(l_order);
+            //dap_string_append(l_string_ret, "\n");
+        }
+    }
+    // return str from dap_string_t
+    return dap_string_free(l_string_ret, false);
+}
+
+/**
+ * Check  VPN server
+ *
+ * return: 0 Ok, <0 Error
+ */
+int dap_chain_net_vpn_client_check(dap_chain_net_t *a_net, const char *a_ipv4_str, const char *a_ipv6_str, int a_port, size_t a_data_size_to_send, size_t a_data_size_to_recv, int a_timeout_test_ms)
+{
+    // default 10k
+    if(a_data_size_to_send==-1)
+        a_data_size_to_send = 10240;
+    if(a_data_size_to_recv==-1)
+        a_data_size_to_recv = 10240;
+    // default 10 sec = 10000 ms
+    if(a_timeout_test_ms==-1)
+        a_timeout_test_ms = 10000;
+    // default 5 sec = 5000 ms
+    int l_timeout_conn_ms = 5000;
+
+    int l_ret = 0;
+    if(!a_ipv4_str) // && !a_ipv6_str)
+        return -1;
+    if(!s_node_info)
+        s_node_info = DAP_NEW_Z(dap_chain_node_info_t);
+    s_node_info->hdr.ext_port = a_port;
+
+
+    // measuring connection time
+    struct timeval l_t;
+    gettimeofday(&l_t, NULL);//get_cur_time_msec
+    long l_t1 = (long) l_t.tv_sec * 1000 + l_t.tv_usec / 1000;
+
+    dap_client_stage_t l_stage_target = STAGE_STREAM_STREAMING; //DAP_CLIENT_STAGE_STREAM_CTL;//STAGE_STREAM_STREAMING;
+    const char l_active_channels[] = { dap_stream_ch_chain_net_srv_get_id(), 0 }; //only R, without S
+    if(a_ipv4_str)
+        inet_pton(AF_INET, a_ipv4_str, &(s_node_info->hdr.ext_addr_v4));
+    if(a_ipv6_str)
+        inet_pton(AF_INET6, a_ipv6_str, &(s_node_info->hdr.ext_addr_v6));
+
+    s_vpn_client = dap_chain_client_connect(s_node_info, l_stage_target, l_active_channels);
+    if(!s_vpn_client) {
+        log_it(L_ERROR, "Can't connect to VPN server=%s:%d", a_ipv4_str, a_port);
+        // clean client struct
+        dap_chain_node_client_close(s_vpn_client);
+        DAP_DELETE(s_node_info);
+        s_node_info = NULL;
+        return -2;
+    }
+    // wait connected
+    int l_timeout_ms = l_timeout_conn_ms; //5 sec = 5000 ms
+    int l_res = dap_chain_node_client_wait(s_vpn_client, NODE_CLIENT_STATE_CONNECTED, l_timeout_ms);
+    if(l_res) {
+        log_it(L_ERROR, "No response from VPN server=%s:%d", a_ipv4_str, a_port);
+        // clean client struct
+        dap_chain_node_client_close(s_vpn_client);
+        DAP_DELETE(s_node_info);
+        s_node_info = NULL;
+        return -3;
+    }
+
+    gettimeofday(&l_t, NULL);
+    long l_t2 = (long) l_t.tv_sec * 1000 + l_t.tv_usec / 1000;
+    int l_dtime_connect_ms = l_t2-l_t1;
+
+    //l_ret = dap_chain_net_vpn_client_tun_init(a_ipv4_str);
+
+    // send first packet to server
+    {
+        uint8_t l_ch_id = dap_stream_ch_chain_net_srv_get_id(); // Channel id for chain net request = 'R'
+        dap_stream_ch_t *l_ch = dap_client_get_stream_ch(s_vpn_client->client, l_ch_id);
+        if(l_ch) {
+            dap_stream_ch_chain_net_srv_pkt_test_t *l_request = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_test_t, sizeof(dap_stream_ch_chain_net_srv_pkt_test_t) + a_data_size_to_send);
+            l_request->net_id.uint64 = a_net->pub.id.uint64;
+            l_request->srv_uid.uint64 = DAP_CHAIN_NET_SRV_VPN_ID;
+            l_request->data_size_send = a_data_size_to_send;
+            l_request->data_size_recv = a_data_size_to_recv;
+            l_request->data_size = a_data_size_to_send;
+            randombytes(l_request->data, a_data_size_to_send);
+            dap_chain_hash_fast_t l_data_hash;
+            dap_hash_fast(l_request->data, l_request->data_size, &l_request->data_hash);
+            if(a_ipv4_str)
+                memcpy(l_request->ip_recv, a_ipv4_str, min(sizeof(l_request->ip_recv), strlen(a_ipv4_str)));
+
+            l_request->time_connect_ms = l_dtime_connect_ms;
+            gettimeofday(&l_request->send_time1, NULL);
+            size_t l_request_size = l_request->data_size + sizeof(dap_stream_ch_chain_net_srv_pkt_test_t);
+            dap_stream_ch_pkt_write(l_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_CHECK_REQUEST, l_request, l_request_size);
+            dap_stream_ch_set_ready_to_write(l_ch, true);
+            DAP_DELETE(l_request);
+        }
+    }
+    // wait testing
+    //int timeout_test_ms = 10000; //10 sec = 10000 ms
+    a_timeout_test_ms -=l_dtime_connect_ms;
+    // timeout not less then 5 sec
+    if(a_timeout_test_ms<5000)
+        a_timeout_test_ms = 5000;
+    l_res = dap_chain_node_client_wait(s_vpn_client, NODE_CLIENT_STATE_CHECKED, a_timeout_test_ms);
+    if(l_res) {
+        log_it(L_ERROR, "No response from VPN server=%s:%d", a_ipv4_str, a_port);
+    }
+    else{
+        log_it(L_NOTICE, "Got response from VPN server=%s:%d", a_ipv4_str, a_port);
+    }
+    // clean client struct
+    dap_chain_node_client_close(s_vpn_client);
+    DAP_DELETE(s_node_info);
+    s_node_info = NULL;
+    if(l_res)
+        return -3;
+    return l_ret;
+}
+
+
 /**
  * Start VPN client
  *
@@ -728,7 +893,13 @@ int dap_chain_net_vpn_client_init(dap_config_t * g_config)
 
     // vpn client command
     dap_chain_node_cli_cmd_item_create ("vpn_client", com_vpn_client, NULL, "VPN client control",
-    "vpn_client [start -addr <server address> -port <server port>| stop | status] -net <net name>\n");
+    "vpn_client [start -addr <server address> -port <server port>| stop | status] -net <net name>\n"
+    "vpn_client init -w <wallet name> -token <token name> -value <value> -net <net name>\n"
+            "vpn_client stop -net <net name>\n"
+            "vpn_client status -net <net name>\n"
+            "vpn_client check -addr <ip addr> -port <port> -net <net name>\n"
+            "vpn_client check result -net <net name> [-H hex|base58(default)]\n"
+            );
 
 
     return dap_chain_net_srv_client_vpn_init(g_config);
diff --git a/modules/service/vpn/include/dap_chain_net_srv_vpn_cdb_server_list.h b/modules/service/vpn/include/dap_chain_net_srv_vpn_cdb_server_list.h
index 6aaacc975870a5f18986c1754649272a6a9731e0..ce8da913514d543fe562a4385887d21575d83a9c 100644
--- a/modules/service/vpn/include/dap_chain_net_srv_vpn_cdb_server_list.h
+++ b/modules/service/vpn/include/dap_chain_net_srv_vpn_cdb_server_list.h
@@ -31,6 +31,8 @@
 
 struct dap_http;
 
+int get_order_state(dap_chain_node_addr_t a_node_addr);
+
 int dap_chain_net_srv_vpn_cdb_server_list_init(void);
 void dap_chain_net_srv_vpn_cdb_server_list_deinit(void);
 void dap_chain_net_srv_vpn_cdb_server_list_add_proc(struct dap_http * sh, const char * url);
diff --git a/modules/service/vpn/include/dap_chain_net_vpn_client.h b/modules/service/vpn/include/dap_chain_net_vpn_client.h
index 4f613e02c8c88dd41c320e0c2a901948b87fe60c..c97f694c0adbdc5e1243d759b2ba1c63dc8d5246 100644
--- a/modules/service/vpn/include/dap_chain_net_vpn_client.h
+++ b/modules/service/vpn/include/dap_chain_net_vpn_client.h
@@ -42,6 +42,9 @@ dap_stream_ch_t* dap_chain_net_vpn_client_get_stream_ch(void);
 int dap_chain_net_vpn_client_update(dap_chain_net_t *a_net, const char *a_wallet_name, const char *a_str_token, uint64_t a_value_datoshi);
 int dap_chain_net_vpn_client_get_wallet_info(dap_chain_net_t *a_net, char **a_wallet_name, char **a_str_token, uint64_t *a_value_datoshi);
 
+char *dap_chain_net_vpn_client_check_result(dap_chain_net_t *a_net, const char* a_hash_out_type);
+int dap_chain_net_vpn_client_check(dap_chain_net_t *a_net, const char *a_ipv4_str, const char *a_ipv6_str, int a_port, size_t a_data_size_to_send, size_t a_data_size_to_recv, int a_timeout_test_ms);
+
 int dap_chain_net_vpn_client_start(dap_chain_net_t *a_net, const char *a_ipv4_str, const char *a_ipv6_str, int a_port);
 int dap_chain_net_vpn_client_stop(void);
 dap_chain_net_vpn_client_status_t dap_chain_net_vpn_client_status(void);