diff --git a/modules/chain/dap_chain_ledger.c b/modules/chain/dap_chain_ledger.c
index 9bfd287bca26310bf6a2c346afcfcd9d87cf5316..db38b05ab6b64d751d3bbb0df1033f71b690f3b4 100644
--- a/modules/chain/dap_chain_ledger.c
+++ b/modules/chain/dap_chain_ledger.c
@@ -50,6 +50,7 @@
 #include "dap_strfuncs.h"
 #include "dap_config.h"
 #include "dap_cert.h"
+#include "dap_timerfd.h"
 #include "dap_chain_datum_tx_token.h"
 #include "dap_chain_datum_token.h"
 #include "dap_chain_mempool.h"
@@ -201,17 +202,24 @@ typedef struct dap_ledger_private {
     dap_chain_cell_id_t local_cell_id;
 
     bool load_mode;
+    // TPS section
+    dap_timerfd_t *tps_timer;
+    struct timespec tps_start_time;
+    struct timespec tps_current_time;
+    struct timespec tps_end_time;
+    size_t tps_count;
 } dap_ledger_private_t;
 #define PVT(a) ( (dap_ledger_private_t* ) a->_internal )
 
 
 static  dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger,
         const dap_chain_addr_t *a_addr, const char * a_token, dap_chain_hash_fast_t *a_tx_first_hash);
-
 static void s_treshold_emissions_proc( dap_ledger_t * a_ledger);
 static void s_treshold_txs_proc( dap_ledger_t * a_ledger);
 static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_item_t *a_token_item , dap_chain_datum_token_t * a_token, size_t a_token_size);
 static int s_ledger_permissions_check(dap_chain_ledger_token_item_t *  a_token_item, uint16_t a_permission_id, const void * a_data,size_t a_data_size );
+static bool s_ledger_tps_callback(void *a_arg);
+
 static size_t s_treshold_emissions_max = 1000;
 static size_t s_treshold_txs_max = 10000;
 static bool s_debug_more = false;
@@ -1148,6 +1156,8 @@ dap_ledger_t* dap_chain_ledger_create(uint16_t a_check_flags, char *a_net_name)
 
     log_it(L_DEBUG,"Created ledger \"%s\"",a_net_name);
     l_ledger_priv->load_mode = true;
+    l_ledger_priv->tps_timer = NULL;
+    l_ledger_priv->tps_count = 0;
     if (dap_config_get_item_bool_default(g_config, "ledger", "cached", true)) {
         // load ledger cache from GDB
         dap_chain_ledger_load_cache(l_ledger);
@@ -2238,6 +2248,13 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx,
     dap_list_t *l_list_tx_out = NULL;
     dap_chain_ledger_tx_item_t *l_item_tmp = NULL;
 
+    if (!l_ledger_priv->tps_timer) {
+        clock_gettime(CLOCK_REALTIME, &l_ledger_priv->tps_start_time);
+        l_ledger_priv->tps_current_time.tv_sec = l_ledger_priv->tps_start_time.tv_sec;
+        l_ledger_priv->tps_current_time.tv_nsec = l_ledger_priv->tps_start_time.tv_nsec;
+        l_ledger_priv->tps_count = 0;
+        l_ledger_priv->tps_timer = dap_timerfd_start(500, s_ledger_tps_callback, l_ledger_priv);
+    }
     dap_chain_hash_fast_t *l_tx_hash = dap_chain_node_datum_tx_calc_hash(a_tx);
     char l_tx_hash_str[70];
     dap_chain_hash_fast_to_str(l_tx_hash,l_tx_hash_str,sizeof(l_tx_hash_str));
@@ -2540,7 +2557,7 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx,
         l_item_tmp = DAP_NEW_Z(dap_chain_ledger_tx_item_t);
         memcpy(&l_item_tmp->tx_hash_fast, l_tx_hash, sizeof(dap_chain_hash_fast_t));
         l_item_tmp->tx = DAP_NEW_SIZE(dap_chain_datum_tx_t, dap_chain_datum_tx_get_size(a_tx));
-        l_item_tmp->cache_data.ts_created = (time_t) a_tx->header.ts_created;
+        l_item_tmp->cache_data.ts_created = time(NULL); // Time of transasction added to ledger
         dap_list_t *l_tist_tmp = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_OUT_ALL, &l_item_tmp->cache_data.n_outs);
         // If debug mode dump the UTXO
         if (dap_log_level_get() == L_DEBUG && s_debug_more) {
@@ -2569,7 +2586,9 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx,
         pthread_rwlock_wrlock(&l_ledger_priv->ledger_rwlock);
         HASH_ADD(hh, l_ledger_priv->ledger_items, tx_hash_fast, sizeof(dap_chain_hash_fast_t), l_item_tmp); // tx_hash_fast: name of key field
         pthread_rwlock_unlock(&l_ledger_priv->ledger_rwlock);
-
+        // Count TPS
+        clock_gettime(CLOCK_REALTIME, &l_ledger_priv->tps_end_time);
+        l_ledger_priv->tps_count++;
         // Add it to cache
         uint8_t *l_tx_cache = DAP_NEW_Z_SIZE(uint8_t, l_tx_size + sizeof(l_item_tmp->cache_data));
         memcpy(l_tx_cache, &l_item_tmp->cache_data, sizeof(l_item_tmp->cache_data));
@@ -2590,6 +2609,19 @@ FIN:
     return ret;
 }
 
+static bool s_ledger_tps_callback(void *a_arg)
+{
+    dap_ledger_private_t *l_ledger_pvt = (dap_ledger_private_t *)a_arg;
+    if (l_ledger_pvt->tps_current_time.tv_sec != l_ledger_pvt->tps_end_time.tv_sec ||
+            l_ledger_pvt->tps_current_time.tv_nsec != l_ledger_pvt->tps_end_time.tv_nsec) {
+        l_ledger_pvt->tps_current_time.tv_sec = l_ledger_pvt->tps_end_time.tv_sec;
+        l_ledger_pvt->tps_current_time.tv_nsec = l_ledger_pvt->tps_end_time.tv_nsec;
+        return true;
+    }
+    l_ledger_pvt->tps_timer = NULL;
+    return false;
+}
+
 int dap_chain_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx)
 {
     if (PVT(a_ledger)->load_mode) {
@@ -2672,7 +2704,6 @@ int dap_chain_ledger_tx_remove(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_
 void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db)
 {
     dap_ledger_private_t *l_ledger_priv = PVT(a_ledger);
-    const int l_hash_str_size = DAP_CHAIN_HASH_FAST_SIZE * 2 + 2;
     pthread_rwlock_wrlock(&l_ledger_priv->ledger_rwlock);
     pthread_rwlock_wrlock(&l_ledger_priv->tokens_rwlock);
     pthread_rwlock_wrlock(&l_ledger_priv->treshold_emissions_rwlock);
@@ -2814,6 +2845,22 @@ uint64_t dap_chain_ledger_count_from_to(dap_ledger_t * a_ledger, time_t a_ts_fro
     return l_ret;
 }
 
+size_t dap_chain_ledger_count_tps(dap_ledger_t *a_ledger, struct timespec *a_ts_from, struct timespec *a_ts_to)
+{
+    if (!a_ledger)
+        return 0;
+    dap_ledger_private_t *l_ledger_priv = PVT(a_ledger);
+    if (a_ts_from) {
+        a_ts_from->tv_sec = l_ledger_priv->tps_start_time.tv_sec;
+        a_ts_from->tv_nsec = l_ledger_priv->tps_start_time.tv_nsec;
+    }
+    if (a_ts_to) {
+        a_ts_to->tv_sec = l_ledger_priv->tps_end_time.tv_sec;
+        a_ts_to->tv_nsec = l_ledger_priv->tps_end_time.tv_nsec;
+    }
+    return l_ledger_priv->tps_count;
+}
+
 /**
  * Check whether used 'out' items
  */
diff --git a/modules/chain/include/dap_chain_ledger.h b/modules/chain/include/dap_chain_ledger.h
index cce692b50d1f4f8679ad51373e1236c2195ea6f6..2896e6cd396c433c62a0c21f6bb3fd17d2f236ca 100644
--- a/modules/chain/include/dap_chain_ledger.h
+++ b/modules/chain/include/dap_chain_ledger.h
@@ -175,6 +175,7 @@ void dap_chain_ledger_load_end(dap_ledger_t *a_ledger);
 unsigned dap_chain_ledger_count(dap_ledger_t *a_ledger);
 
 uint64_t dap_chain_ledger_count_from_to(dap_ledger_t * a_ledger, time_t a_ts_from, time_t a_ts_to );
+size_t dap_chain_ledger_count_tps(dap_ledger_t *a_ledger, struct timespec *a_ts_from, struct timespec *a_ts_to);
 
 /**
  * Check whether used 'out' items
diff --git a/modules/global-db/dap_chain_global_db_driver_sqlite.c b/modules/global-db/dap_chain_global_db_driver_sqlite.c
index b9060cd5cafd12f93c5ff78426e8b66001076855..334b0d3fd3ecbbb96f48e884a547040374b983f7 100644
--- a/modules/global-db/dap_chain_global_db_driver_sqlite.c
+++ b/modules/global-db/dap_chain_global_db_driver_sqlite.c
@@ -86,9 +86,9 @@ static int dap_db_driver_sqlite_exec(sqlite3 *l_db, const char *l_query, char **
 
 static sqlite3 *s_sqlite_get_connection(void)
 {
-	if (pthread_rwlock_wrlock(&s_db_rwlock) == EDEADLK) {
-		return NULL;
-	}
+    if (pthread_rwlock_wrlock(&s_db_rwlock) == EDEADLK) {
+        return s_trans;
+    }
 
 	sqlite3 *l_ret = NULL;
 	for (int i = 0; i < DAP_SQLITE_POOL_COUNT; i++) {
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index 4be57955c7b10c687da469d3b7e78ce799b858b9..0581e7e5a59dd0b3b4951a131f1837ef65bcfce6 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -185,6 +185,7 @@ typedef struct dap_chain_net_pvt{
     // General rwlock for structure
     pthread_rwlock_t rwlock;
 
+    dap_list_t *notify_callbacks;
 } dap_chain_net_pvt_t;
 
 typedef struct dap_chain_net_item{
@@ -264,8 +265,6 @@ static bool s_seed_mode = false;
 
 static uint8_t *dap_chain_net_set_acl(dap_chain_hash_fast_t *a_pkey_hash);
 
-static dap_global_db_obj_callback_notify_t s_srv_callback_notify = NULL;
-
 /**
  * @brief
  * init network settings from cellrame-node.cfg file
@@ -388,11 +387,12 @@ dap_chain_net_state_t dap_chain_net_get_target_state(dap_chain_net_t *a_net)
  * 
  * @param a_callback dap_global_db_obj_callback_notify_t callback function
  */
-void dap_chain_net_set_srv_callback_notify(dap_global_db_obj_callback_notify_t a_callback)
+void dap_chain_net_add_notify_callback(dap_chain_net_t *a_net, dap_global_db_obj_callback_notify_t a_callback)
 {
-    s_srv_callback_notify = a_callback;
+   PVT(a_net)->notify_callbacks = dap_list_append(PVT(a_net)->notify_callbacks, a_callback);
 }
 
+
 /**
  * @brief if current network in ONLINE state send to all connected node
  * executes, when you add data to gdb chain (class=gdb in chain config)
@@ -459,16 +459,17 @@ void dap_chain_net_sync_gdb_broadcast(void *a_arg, const char a_op_code, const c
  * @param a_value buffer with data
  * @param a_value_len buffer size
  */
-static void s_gbd_history_callback_notify (void * a_arg, const char a_op_code, const char * a_group,
-                                                     const char * a_key, const void * a_value, const size_t a_value_len)
+static void s_gbd_history_callback_notify(void *a_arg, const char a_op_code, const char *a_group,
+                                          const char *a_key, const void *a_value, const size_t a_value_len)
 {
     if (!a_arg) {
         return;
     }
-    dap_chain_node_mempool_autoproc_notify(a_arg, a_op_code, a_group, a_key, a_value, a_value_len);
-    dap_chain_net_sync_gdb_broadcast(a_arg, a_op_code, a_group, a_key, a_value, a_value_len);
-    if (s_srv_callback_notify) {
-        s_srv_callback_notify(a_arg, a_op_code, a_group, a_key, a_value, a_value_len);
+    dap_chain_net_t *l_net = (dap_chain_net_t *)a_arg;
+    for (dap_list_t *it = PVT(l_net)->notify_callbacks; it; it = PVT(l_net)->notify_callbacks->next) {
+        dap_global_db_obj_callback_notify_t l_callback = (dap_global_db_obj_callback_notify_t)it->data;
+        if (l_callback)
+            l_callback(a_arg, a_op_code, a_group, a_key, a_value, a_value_len);
     }
 }
 
@@ -1539,60 +1540,42 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply)
         if ( !dap_strcmp(l_sync_mode_str,"all") )
             dap_chain_net_get_flag_sync_from_zero(l_net);
 
-        if ( l_stats_str ){
-            if ( strcmp(l_stats_str,"tx") == 0 ) {
+        if (l_stats_str) {
+            char l_from_str_new[50], l_to_str_new[50];
+            const char c_time_fmt[]="%Y-%m-%d_%H:%M:%S";
+            struct tm l_from_tm = {}, l_to_tm = {};
+            if (strcmp(l_stats_str,"tx") == 0) {
                 const char *l_to_str = NULL;
-                struct tm l_to_tm = {0};
-
                 const char *l_from_str = NULL;
-                struct tm l_from_tm = {0};
-
                 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);
-
-                if (l_from_str ) {
+                time_t l_ts_now = time(NULL);
+                if (l_from_str) {
                     strptime( (char *)l_from_str, c_time_fmt, &l_from_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
-                    time_t l_ts_now = time(NULL);
-                    localtime_r(&l_ts_now, &l_to_tm);
-                }
-
-                if ( l_prev_sec_str ){
-                    time_t l_ts_now = time(NULL);
+                    if (l_to_str) {
+                        strptime( (char *)l_to_str, c_time_fmt, &l_to_tm );
+                    } else { // If not set '-to' - we set up current time
+                        localtime_r(&l_ts_now, &l_to_tm);
+                    }
+                } else if (l_prev_sec_str) {
                     l_ts_now -= strtol( l_prev_sec_str, NULL,10 );
                     localtime_r(&l_ts_now, &l_from_tm );
-                }/*else if ( l_from_str == NULL ){ // If not set '-from' we set up current time minus 10 seconds
-                    time_t l_ts_now = time(NULL);
-                    l_ts_now -= 10;
+                } else if ( l_from_str == NULL ) { // If not set '-from' we set up current time minus 60 seconds
+                    l_ts_now -= 60;
                     localtime_r(&l_ts_now, &l_from_tm );
-                }*/
-
+                }
                 // Form timestamps from/to
                 time_t l_from_ts = mktime(&l_from_tm);
                 time_t l_to_ts = mktime(&l_to_tm);
-
                 // 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 );
-
-
                 dap_string_t * l_ret_str = dap_string_new("Transactions statistics:\n");
-
                 dap_string_append_printf( l_ret_str, "\tFrom: %s\tTo: %s\n", l_from_str_new, l_to_str_new);
                 log_it(L_INFO, "Calc TPS from %s to %s", l_from_str_new, l_to_str_new);
                 uint64_t l_tx_count = dap_chain_ledger_count_from_to ( l_net->pub.ledger, l_from_ts, l_to_ts);
@@ -1602,6 +1585,27 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply)
                 dap_string_append_printf( l_ret_str, "\tTotal:  %"DAP_UINT64_FORMAT_U"\n", l_tx_count );
                 dap_chain_node_cli_set_reply_text( a_str_reply, l_ret_str->str );
                 dap_string_free( l_ret_str, false );
+            } else if (strcmp(l_stats_str, "tps") == 0) {
+                struct timespec l_from_time_acc = {}, l_to_time_acc = {};
+                dap_string_t * l_ret_str = dap_string_new("Transactions per second peak values:\n");
+                size_t l_tx_num = dap_chain_ledger_count_tps(l_net->pub.ledger, &l_from_time_acc, &l_to_time_acc);
+                if (l_tx_num) {
+                    localtime_r(&l_from_time_acc.tv_sec, &l_from_tm);
+                    strftime(l_from_str_new, sizeof(l_from_str_new), c_time_fmt, &l_from_tm);
+                    localtime_r(&l_to_time_acc.tv_sec, &l_to_tm);
+                    strftime(l_to_str_new, sizeof(l_to_str_new), c_time_fmt, &l_to_tm);
+                    dap_string_append_printf(l_ret_str, "\tFrom: %s\tTo: %s\n", l_from_str_new, l_to_str_new);
+                    uint64_t l_diff_ns = (l_to_time_acc.tv_sec - l_from_time_acc.tv_sec) * 1000000000 +
+                                            l_to_time_acc.tv_nsec - l_from_time_acc.tv_nsec;
+                    long double l_tps = (long double)(l_tx_num * 1000000000) / (long double)(l_diff_ns);
+                    dap_string_append_printf(l_ret_str, "\tSpeed:  %.3Lf TPS\n", l_tps);
+                }
+                dap_string_append_printf(l_ret_str, "\tTotal:  %zu\n", l_tx_num);
+                dap_chain_node_cli_set_reply_text(a_str_reply, l_ret_str->str);
+                dap_string_free(l_ret_str, false);
+            } else {
+                dap_chain_node_cli_set_reply_text(a_str_reply,
+                                                  "Subcommand 'stats' requires one of parameter: tx, tps\n");
             }
         } else if ( l_go_str){
             if ( strcmp(l_go_str,"online") == 0 ) {
@@ -1615,16 +1619,17 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply)
                                                   c_net_states[NET_STATE_OFFLINE]);
                 dap_chain_net_state_go_to(l_net, NET_STATE_OFFLINE);
 
-            }
-            else if(strcmp(l_go_str, "sync") == 0) {
+            } else if (strcmp(l_go_str, "sync") == 0) {
                 dap_chain_node_cli_set_reply_text(a_str_reply, "Network \"%s\" resynchronizing",
                                                   l_net->pub.name);
                 if (PVT(l_net)->state_target == NET_STATE_ONLINE)
                     dap_chain_net_state_go_to(l_net, NET_STATE_ONLINE);
                 else
                     dap_chain_net_state_go_to(l_net, NET_STATE_SYNC_CHAINS);
+            } else {
+                dap_chain_node_cli_set_reply_text(a_str_reply,
+                                                  "Subcommand 'go' requires one of parameters: online, offline, sync\n");
             }
-
         } else if ( l_get_str){
             if ( strcmp(l_get_str,"status") == 0 ) {
                 s_set_reply_text_node_status(a_str_reply, l_net);
@@ -1679,7 +1684,7 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply)
                 dap_chain_node_cli_set_reply_text(a_str_reply,"Stopped network\n");
             }else {
                 dap_chain_node_cli_set_reply_text(a_str_reply,
-                                                  "Subcommand \"link\" requires one of parameter: list\n");
+                                                  "Subcommand 'link' requires one of parameters: list, add, del, info, disconnect_all\n");
                 ret = -3;
             }
 
@@ -1705,7 +1710,7 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply)
 
             } else {
                 dap_chain_node_cli_set_reply_text(a_str_reply,
-                                                  "Subcommand \"sync\" requires one of parameter: all,gdb,chains\n");
+                                                  "Subcommand 'sync' requires one of parameters: all, gdb, chains\n");
                 ret = -2;
             }
         } else if (l_ca_str) {
@@ -1808,7 +1813,7 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply)
                 return 0;
             } else {
                 dap_chain_node_cli_set_reply_text(a_str_reply,
-                                                  "Subcommand \"ca\" requires one of parameter: add, list, del\n");
+                                                  "Subcommand 'ca' requires one of parameter: add, list, del\n");
                 ret = -5;
             }
         } else if (l_ledger_str && !strcmp(l_ledger_str, "reload")) {
@@ -1837,7 +1842,7 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply)
             } while (l_processed);
         } else {
             dap_chain_node_cli_set_reply_text(a_str_reply,
-                                              "Command requires one of subcomand: sync, link, go, get, stats, ca, ledger");
+                                              "Command 'net' requires one of subcomands: sync, link, go, get, stats, ca, ledger");
             ret = -1;
         }
 
@@ -2376,7 +2381,7 @@ int s_net_load(const char * a_net_name, uint16_t a_acl_idx)
         }
         l_net_pvt->load_mode = false;
         dap_chain_ledger_load_end(l_net->pub.ledger);
-
+        dap_chain_net_add_notify_callback(l_net, dap_chain_net_sync_gdb_broadcast);
         if (l_target_state != l_net_pvt->state_target)
             dap_chain_net_state_go_to(l_net, l_target_state);
 
diff --git a/modules/net/dap_chain_node.c b/modules/net/dap_chain_node.c
index 89717fd4ef0ba0625676ba415370353baca2a0ef..f5e31813c9322d7f554410cae2c1a3bd61c197b7 100644
--- a/modules/net/dap_chain_node.c
+++ b/modules/net/dap_chain_node.c
@@ -291,6 +291,7 @@ bool dap_chain_node_mempool_autoproc_init()
                 }
                 DAP_DELETE(l_gdb_group_mempool);
             }
+            dap_chain_net_add_notify_callback(l_net_list[i], dap_chain_node_mempool_autoproc_notify);
         }
     }
     DAP_DELETE(l_net_list);
diff --git a/modules/net/dap_chain_node_client.c b/modules/net/dap_chain_node_client.c
index 1c385006668366fb5971a8bc196ccdd5898f3939..f8fae3e93022a16c582dbc182ecc405396291cc4 100644
--- a/modules/net/dap_chain_node_client.c
+++ b/modules/net/dap_chain_node_client.c
@@ -978,7 +978,8 @@ int dap_chain_node_client_set_callbacks(dap_client_t *a_client, uint8_t a_ch_id)
             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);
                 if (l_node_client->callbacks.srv_pkt_in) {
-                    l_ch_chain->notify_callback = l_node_client->callbacks.srv_pkt_in;
+                    l_ch_chain->notify_callback = (dap_stream_ch_chain_net_srv_callback_packet_t)
+                                                             l_node_client->callbacks.srv_pkt_in;
                     l_ch_chain->notify_callback_arg = l_node_client->callbacks_arg;
                 } else {
                     l_ch_chain->notify_callback = s_ch_chain_callback_notify_packet_R;
diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h
index 59fcfd8b83a3deb9871544e844af55ebe58ec2e6..a9701a173791a6313f2c3404764e50bf1fd6aa2f 100644
--- a/modules/net/include/dap_chain_net.h
+++ b/modules/net/include/dap_chain_net.h
@@ -176,7 +176,7 @@ bool dap_chain_net_get_add_gdb_group(dap_chain_net_t *a_net, dap_chain_node_addr
 
 int dap_chain_net_verify_datum_for_add(dap_chain_net_t *a_net, dap_chain_datum_t * a_datum );
 void dap_chain_net_dump_datum(dap_string_t *a_str_out, dap_chain_datum_t *a_datum, const char *a_hash_out_type);
-void dap_chain_net_set_srv_callback_notify(dap_global_db_obj_callback_notify_t a_callback);
+void dap_chain_net_add_notify_callback(dap_chain_net_t *a_net, dap_global_db_obj_callback_notify_t a_callback);
 void dap_chain_net_sync_gdb_broadcast(void *a_arg, const char a_op_code, const char *a_group,
                                       const char *a_key, const void *a_value, const size_t a_value_len);
 
diff --git a/modules/net/srv/dap_chain_net_srv_order.c b/modules/net/srv/dap_chain_net_srv_order.c
index 361a275c2eca7c8912d63c76e93a16bdc8630582..8ba00122c61ca1682b4708ca0fa531d113da87a1 100644
--- a/modules/net/srv/dap_chain_net_srv_order.c
+++ b/modules/net/srv/dap_chain_net_srv_order.c
@@ -56,6 +56,11 @@ char *s_server_continents[]={
 		"Antarctica"
  };
 
+struct dap_order_notify {
+    dap_chain_net_t *net;
+    dap_global_db_obj_callback_notify_t callback;
+};
+static dap_list_t *s_order_notify_callbacks = NULL;
 static void s_srv_order_callback_notify(void *a_arg, const char a_op_code, const char *a_group,
                                    const char *a_key, const void *a_value, const size_t a_value_len);
 
@@ -65,7 +70,11 @@ static void s_srv_order_callback_notify(void *a_arg, const char a_op_code, const
  */
 int dap_chain_net_srv_order_init(void)
 {
-    dap_chain_net_set_srv_callback_notify(s_srv_order_callback_notify);
+    uint16_t l_net_count;
+    dap_chain_net_t **l_net_list = dap_chain_net_list(&l_net_count);
+    for (uint16_t i = 0; i < l_net_count; i++) {
+        dap_chain_net_add_notify_callback(l_net_list[i], s_srv_order_callback_notify);
+    }
 	//geoip_info_t *l_ipinfo = chain_net_geoip_get_ip_info("8.8.8.8");
     return 0;
 }
@@ -75,7 +84,7 @@ int dap_chain_net_srv_order_init(void)
  */
 void dap_chain_net_srv_order_deinit()
 {
-
+    dap_list_free_full(s_order_notify_callbacks, free);
 }
 
 size_t dap_chain_net_srv_order_get_size(dap_chain_net_srv_order_t *a_order)
@@ -521,37 +530,54 @@ static void s_srv_order_callback_notify(void *a_arg, const char a_op_code, const
                                    const char *a_key, const void *a_value, const size_t a_value_len)
 {
     UNUSED(a_value_len);
-    if (!a_arg || !a_value || a_op_code != 'a' || !dap_config_get_item_bool_default(g_config, "srv", "order_signed_only", false)) {
+    if (!a_arg || !a_key) {
         return;
     }
     dap_chain_net_t *l_net = (dap_chain_net_t *)a_arg;
     char *l_gdb_group_str = dap_chain_net_srv_order_get_gdb_group(l_net);
     if (!strcmp(a_group, l_gdb_group_str)) {
-        dap_chain_net_srv_order_t *l_order = (dap_chain_net_srv_order_t *)a_value;
-        if (l_order->version != 2) {
-            dap_chain_global_db_gr_del(dap_strdup(a_key), a_group);
-        } else {
-            dap_sign_t *l_sign = (dap_sign_t *)&l_order->ext_n_sign[l_order->ext_size];
-            if (!dap_sign_verify_size(l_sign, a_value_len) ||
-                    dap_sign_verify(l_sign, l_order, sizeof(dap_chain_net_srv_order_t) + l_order->ext_size) != 1) {
-                dap_chain_global_db_gr_del(dap_strdup(a_key), a_group);
-                DAP_DELETE(l_gdb_group_str);
-                return;
+        for (dap_list_t *it = s_order_notify_callbacks; it; it = s_order_notify_callbacks->next) {
+            struct dap_order_notify *l_notifier = (struct dap_order_notify *)it->data;
+            if ((l_notifier->net == NULL || l_notifier->net == l_net) &&
+                        l_notifier->callback) {
+                l_notifier->callback(a_arg, a_op_code, a_group, a_key, a_value, a_value_len);
             }
-            /*dap_chain_hash_fast_t l_pkey_hash;
-            if (!dap_sign_get_pkey_hash(l_sign, &l_pkey_hash)) {
+        }
+        if (a_value && a_op_code != 'a' && dap_config_get_item_bool_default(g_config, "srv", "order_signed_only", false)) {
+            dap_chain_net_srv_order_t *l_order = (dap_chain_net_srv_order_t *)a_value;
+            if (l_order->version != 2) {
                 dap_chain_global_db_gr_del(dap_strdup(a_key), a_group);
-                DAP_DELETE(l_gdb_group_str);
-                return;
+            } else {
+                dap_sign_t *l_sign = (dap_sign_t *)&l_order->ext_n_sign[l_order->ext_size];
+                if (!dap_sign_verify_size(l_sign, a_value_len) ||
+                        dap_sign_verify(l_sign, l_order, sizeof(dap_chain_net_srv_order_t) + l_order->ext_size) != 1) {
+                    dap_chain_global_db_gr_del(dap_strdup(a_key), a_group);
+                    DAP_DELETE(l_gdb_group_str);
+                    return;
+                }
+                /*dap_chain_hash_fast_t l_pkey_hash;
+                if (!dap_sign_get_pkey_hash(l_sign, &l_pkey_hash)) {
+                    dap_chain_global_db_gr_del(dap_strdup(a_key), a_group);
+                    DAP_DELETE(l_gdb_group_str);
+                    return;
+                }
+                dap_chain_addr_t l_addr = {};
+                dap_chain_addr_fill(&l_addr, l_sign->header.type, &l_pkey_hash, l_net->pub.id);
+                uint128_t l_balance = dap_chain_ledger_calc_balance(l_net->pub.ledger, &l_addr, l_order->price_ticker);
+                uint64_t l_solvency = dap_chain_uint128_to(l_balance);
+                if (l_solvency < l_order->price && !dap_chain_net_srv_stake_key_delegated(&l_addr)) {
+                    dap_chain_global_db_gr_del(dap_strdup(a_key), a_group);
+                }*/
             }
-            dap_chain_addr_t l_addr = {};
-            dap_chain_addr_fill(&l_addr, l_sign->header.type, &l_pkey_hash, l_net->pub.id);
-            uint128_t l_balance = dap_chain_ledger_calc_balance(l_net->pub.ledger, &l_addr, l_order->price_ticker);
-            uint64_t l_solvency = dap_chain_uint128_to(l_balance);
-            if (l_solvency < l_order->price && !dap_chain_net_srv_stake_key_delegated(&l_addr)) {
-                dap_chain_global_db_gr_del(dap_strdup(a_key), a_group);
-            }*/
         }
-        DAP_DELETE(l_gdb_group_str);
     }
+    DAP_DELETE(l_gdb_group_str);
+}
+
+void dap_chain_net_srv_order_add_notify_callback(dap_chain_net_t *a_net, dap_global_db_obj_callback_notify_t a_callback)
+{
+    struct dap_order_notify *l_notifier = DAP_NEW(struct dap_order_notify);
+    l_notifier->net = a_net;
+    l_notifier->callback = a_callback;
+    s_order_notify_callbacks = dap_list_append(s_order_notify_callbacks, l_notifier);
 }
diff --git a/modules/net/srv/include/dap_chain_net_srv.h b/modules/net/srv/include/dap_chain_net_srv.h
index a66087bb616ca905887e0cca20e0f4eec0abe70c..decccd52e1260d1b7f69895167254010630fbf9a 100755
--- a/modules/net/srv/include/dap_chain_net_srv.h
+++ b/modules/net/srv/include/dap_chain_net_srv.h
@@ -93,8 +93,8 @@ typedef struct dap_chain_net_srv_client_remote
     dap_chain_net_remote_t *net_remote; // For remotes
     uint64_t bytes_received;
     uint64_t bytes_sent;
-    struct dap_chain_net_srv_client *prev;
-    struct dap_chain_net_srv_client *next;
+    struct dap_chain_net_srv_client_remote *prev;
+    struct dap_chain_net_srv_client_remote *next;
 } dap_chain_net_srv_client_remote_t;
 
 
diff --git a/modules/net/srv/include/dap_chain_net_srv_order.h b/modules/net/srv/include/dap_chain_net_srv_order.h
index 5a4d496e0071aa9726dbb2eab5e41b00f13a52a5..bc705106249c6a3920db35ab2e4e89e9a718244c 100644
--- a/modules/net/srv/include/dap_chain_net_srv_order.h
+++ b/modules/net/srv/include/dap_chain_net_srv_order.h
@@ -128,7 +128,7 @@ char *dap_chain_net_srv_order_create(dap_chain_net_t * a_net,
 
 int dap_chain_net_srv_order_save(dap_chain_net_t * a_net, dap_chain_net_srv_order_t *a_order);
 void dap_chain_net_srv_order_dump_to_string(dap_chain_net_srv_order_t *a_order,dap_string_t * a_str_out, const char *a_hash_out_type);
-
+void dap_chain_net_srv_order_add_notify_callback(dap_chain_net_t *a_net, dap_global_db_obj_callback_notify_t a_callback);
 /**
 * @brief dap_chain_net_srv_order_get_gdb_group_mempool
 * @param l_chain
diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c
index 09d11c478ff77fe1badae42dcbebe2f910beab00..3ea4342528cd4cd52f28a931afdf9de514f37aa9 100644
--- a/modules/type/dag/dap_chain_cs_dag.c
+++ b/modules/type/dag/dap_chain_cs_dag.c
@@ -306,6 +306,10 @@ static void s_dap_chain_cs_dag_purge(dap_chain_t *a_chain)
         DAP_DELETE(l_event_current);
     }
     pthread_rwlock_unlock(&l_dag_pvt->events_rwlock);
+    dap_chain_cell_t *l_cell_cur, *l_cell_tmp;
+    HASH_ITER(hh, a_chain->cells, l_cell_cur, l_cell_tmp) {
+        dap_chain_cell_close(l_cell_cur);
+    }
 }
 
 /**