diff --git a/cellframe-sdk.pro b/cellframe-sdk.pro
index e553962e9ab90730f0664d36b8f575024c09db5c..3e1b5e1eaf9b031230e2263a0825adb993fa12a8 100644
--- a/cellframe-sdk.pro
+++ b/cellframe-sdk.pro
@@ -9,24 +9,24 @@ linux: !android {
 
 win32 {
     
-    CONFIG(release, debug | release): sdk_build.commands = "$$shell_path($$PWD/../cellframe-sdk/prod_build/build.sh)" --target windows release -DINSTALL_SDK=1 -DCMAKE_INSTALL_PREFIX=/
-    CONFIG(debug, debug | release): sdk_build.commands = "$$shell_path($$PWD/../cellframe-sdk/prod_build/build.sh)" --target windows rwd -DINSTALL_SDK=1 -DCMAKE_INSTALL_PREFIX=/
+    CONFIG(release, debug | release): sdk_build.commands = "$$shell_path($$PWD/../cellframe-sdk/prod_build/build.sh)" --target windows release -DINSTALL_SDK=1 -DCMAKE_INSTALL_PREFIX=/ -DCELLFRAME_NO_OPTIMIZATION=1
+    CONFIG(debug, debug | release): sdk_build.commands = "$$shell_path($$PWD/../cellframe-sdk/prod_build/build.sh)" --target windows rwd -DINSTALL_SDK=1 -DCMAKE_INSTALL_PREFIX=/ -DCELLFRAME_NO_OPTIMIZATION=1
     
 }
 
 android {
     for (AABI, ANDROID_ABIS) {
         message("Requested ABI: $$AABI")
-        CONFIG(release, debug | release): sdk_build_$${AABI}.commands += $$PWD/../cellframe-sdk/prod_build/build.sh -b $$AABI --target android release -DANDROID_PLATFORM=android-21 -DANDROID_ABI=$$AABI -DANDROID_NATIVE_API_LEVEL=29 -DINSTALL_SDK=1 -DCMAKE_INSTALL_PREFIX=/ -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON
-        CONFIG(debug, debug | release): sdk_build_$${AABI}.commands += $$PWD/../cellframe-sdk/prod_build/build.sh -b $$AABI --target android release -DANDROID_PLATFORM=android-21 -DANDROID_ABI=$$AABI -DANDROID_NATIVE_API_LEVEL=29 -DINSTALL_SDK=1 -DCMAKE_INSTALL_PREFIX=/ -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON
+        CONFIG(release, debug | release): sdk_build_$${AABI}.commands += $$PWD/../cellframe-sdk/prod_build/build.sh -b $$AABI --target android release -DANDROID_PLATFORM=android-21 -DANDROID_ABI=$$AABI -DANDROID_NATIVE_API_LEVEL=29 -DINSTALL_SDK=1 -DCMAKE_INSTALL_PREFIX=/ -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -DCELLFRAME_NO_OPTIMIZATION=1
+        CONFIG(debug, debug | release): sdk_build_$${AABI}.commands += $$PWD/../cellframe-sdk/prod_build/build.sh -b $$AABI --target android release -DANDROID_PLATFORM=android-21 -DANDROID_ABI=$$AABI -DANDROID_NATIVE_API_LEVEL=29 -DINSTALL_SDK=1 -DCMAKE_INSTALL_PREFIX=/ -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -DCELLFRAME_NO_OPTIMIZATION=1
 
     }
 }
 
 mac {
     
-    CONFIG(release, debug | release): sdk_build.commands = $$PWD/../cellframe-sdk/prod_build/build.sh --target osx release -DINSTALL_SDK=1 -DCMAKE_INSTALL_PREFIX=/
-    CONFIG(debug, debug | release): sdk_build.commands = $$PWD/../cellframe-sdk/prod_build/build.sh --target osx rwd -DINSTALL_SDK=1 -DCMAKE_INSTALL_PREFIX=/
+    CONFIG(release, debug | release): sdk_build.commands = $$PWD/../cellframe-sdk/prod_build/build.sh --target osx release -DINSTALL_SDK=1 -DCMAKE_INSTALL_PREFIX=/ -DCELLFRAME_NO_OPTIMIZATION=1
+    CONFIG(debug, debug | release): sdk_build.commands = $$PWD/../cellframe-sdk/prod_build/build.sh --target osx rwd -DINSTALL_SDK=1 -DCMAKE_INSTALL_PREFIX=/ -DCELLFRAME_NO_OPTIMIZATION=1
 
 }
 
diff --git a/dap-sdk b/dap-sdk
index 9e7565c9417bad979e90b83ccd537aecfe7c07f9..f2b762fcfbf3d799029d9a52963b09fefd9e711b 160000
--- a/dap-sdk
+++ b/dap-sdk
@@ -1 +1 @@
-Subproject commit 9e7565c9417bad979e90b83ccd537aecfe7c07f9
+Subproject commit f2b762fcfbf3d799029d9a52963b09fefd9e711b
diff --git a/modules/chain/dap_chain.c b/modules/chain/dap_chain.c
index a09641236e9366f5a51718a70cb9ca72ea8b3233..20c8dfc5bc801e4014bbb9922eee78bb1ec563e1 100644
--- a/modules/chain/dap_chain.c
+++ b/modules/chain/dap_chain.c
@@ -697,7 +697,7 @@ void dap_chain_info_dump_log(dap_chain_t * a_chain)
  * @param a_callback
  * @param a_arg
  */
-void dap_chain_add_callback_notify(dap_chain_t * a_chain, dap_chain_callback_notify_t a_callback, void * a_callback_arg)
+void dap_chain_add_callback_notify(dap_chain_t *a_chain, dap_chain_callback_notify_t a_callback, dap_proc_thread_t *a_thread, void *a_callback_arg)
 {
     if(!a_chain){
         log_it(L_ERROR, "NULL chain passed to dap_chain_add_callback_notify()");
@@ -714,6 +714,7 @@ void dap_chain_add_callback_notify(dap_chain_t * a_chain, dap_chain_callback_not
     }
 
     l_notifier->callback = a_callback;
+    l_notifier->proc_thread = a_thread;
     l_notifier->arg = a_callback_arg;
     pthread_rwlock_wrlock(&a_chain->rwlock);
     a_chain->atom_notifiers = dap_list_append(a_chain->atom_notifiers, l_notifier);
@@ -845,7 +846,7 @@ void dap_chain_atom_notify(dap_chain_cell_t *a_chain_cell, dap_hash_fast_t *a_ha
             .hash = *a_hash,
             .atom = a_chain_cell->chain->is_mapped ? (byte_t*)a_atom : DAP_DUP_SIZE(a_atom, a_atom_size),
             .atom_size = a_atom_size };
-        dap_proc_thread_callback_add_pri(NULL, s_notify_atom_on_thread, l_arg, DAP_QUEUE_MSG_PRIORITY_LOW);
+        dap_proc_thread_callback_add_pri(l_notifier->proc_thread, s_notify_atom_on_thread, l_arg, DAP_QUEUE_MSG_PRIORITY_LOW);
     }
 }
 
diff --git a/modules/chain/dap_chain_ch.c b/modules/chain/dap_chain_ch.c
index 661cffe6df1deb570d75247854259a8feb223170..98eef65ffe41e75028818a9269659657618a5404 100644
--- a/modules/chain/dap_chain_ch.c
+++ b/modules/chain/dap_chain_ch.c
@@ -619,17 +619,16 @@ static bool s_sync_in_chains_callback(void *a_arg)
         return false;
     }
     char *l_atom_hash_str = NULL;
-    l_atom_hash_str = DAP_NEW_STACK_SIZE(char, DAP_CHAIN_HASH_FAST_STR_SIZE); 
-    dap_hash_fast_t l_atom_hash = {}; 
+    dap_hash_fast_t l_atom_hash = { }; 
     dap_hash_fast(l_atom, l_atom_size, &l_atom_hash); 
     if (s_debug_more)
-        dap_get_data_hash_str_static(l_atom, l_atom_size, l_atom_hash_str);
+        l_atom_hash_str = dap_hash_fast_to_str_static(&l_atom_hash);
     dap_chain_atom_verify_res_t l_atom_add_res = l_chain->callback_atom_add(l_chain, l_atom, l_atom_size, &l_atom_hash, false);
     bool l_ack_send = false;
     switch (l_atom_add_res) {
     case ATOM_PASS:
         debug_if(s_debug_more, L_WARNING, "Atom with hash %s for %s:%s not accepted (code ATOM_PASS, already present)",
-                                                l_atom_hash_str, l_chain->net_name, l_chain->name);
+                                          l_atom_hash_str, l_chain->net_name, l_chain->name);
         l_ack_send = true;
         break;
     case ATOM_MOVE_TO_THRESHOLD:
@@ -776,12 +775,9 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
         l_args->addr = a_ch->stream->node;
         l_args->ack_req = true;
         memcpy(l_args->data, l_chain_pkt, l_ch_pkt->hdr.data_size);
-        if (s_debug_more) {
-            char *l_atom_hash_str;
-            dap_get_data_hash_str_static(l_chain_pkt->data, l_chain_pkt_data_size, l_atom_hash_str);
-            log_it(L_INFO, "In: CHAIN pkt: atom hash %s, size %zd, net id %" DAP_UINT64_FORMAT_U ", chain id %" DAP_UINT64_FORMAT_U,
-                    l_atom_hash_str, l_chain_pkt_data_size, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64);
-        }
+        debug_if(s_debug_more, L_INFO, "In: CHAIN pkt: atom hash %s, size %zd, net id %" DAP_UINT64_FORMAT_U ", chain id %" DAP_UINT64_FORMAT_U,
+                                        dap_get_data_hash_str(l_chain_pkt->data, l_chain_pkt_data_size).s, l_chain_pkt_data_size, 
+                                        l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64);
         dap_proc_thread_callback_add(a_ch->stream_worker->worker->proc_queue_input, s_sync_in_chains_callback, l_args);
     } break;
 
@@ -877,7 +873,7 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
         if (l_missed_hash) {
             l_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_LAST, NULL);
             dap_chain_ch_miss_info_t l_miss_info = { .missed_hash = l_request->hash_from,
-                                                     .last_hash = *l_iter->cur_hash,
+                                                     .last_hash = l_iter->cur_hash ? *l_iter->cur_hash : (dap_hash_fast_t){ },
                                                      .last_num = l_iter->cur_num };
             dap_chain_ch_pkt_write_unsafe(a_ch, DAP_CHAIN_CH_PKT_TYPE_CHAIN_MISS,
                                           l_chain_pkt->hdr.net_id, l_chain_pkt->hdr.chain_id,
@@ -1498,11 +1494,8 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
         }
         l_chain_pkt->hdr.data_size = l_chain_pkt_data_size;
         memcpy(l_args->data, l_chain_pkt, l_ch_pkt->hdr.data_size);
-        if (s_debug_legacy) {
-            char *l_atom_hash_str;
-            dap_get_data_hash_str_static(l_chain_pkt->data, l_chain_pkt_data_size, l_atom_hash_str);
-            log_it(L_INFO, "In: CHAIN_OLD pkt: atom hash %s (size %zd)", l_atom_hash_str, l_chain_pkt_data_size);
-        }
+        debug_if(s_debug_legacy, L_INFO, "In: CHAIN_OLD pkt: atom hash %s (size %zd)",
+                                         dap_get_data_hash_str(l_chain_pkt->data, l_chain_pkt_data_size).s, l_chain_pkt_data_size);
         dap_proc_thread_callback_add(a_ch->stream_worker->worker->proc_queue_input, s_sync_in_chains_callback, l_args);
     } break;
 
diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h
index e665a6ae20dbd876aec0d058b388ecf4dad22373..beb262ba03eb3fe930dbbf24599f28b5199d8327 100644
--- a/modules/chain/include/dap_chain.h
+++ b/modules/chain/include/dap_chain.h
@@ -231,8 +231,11 @@ typedef struct dap_chain {
     void * _inheritor; // inheritor object
 } dap_chain_t;
 
+typedef struct dap_proc_thread dap_proc_thread_t;
+
 typedef struct dap_chain_atom_notifier {
     dap_chain_callback_notify_t callback;
+    dap_proc_thread_t *proc_thread;
     void *arg;
 } dap_chain_atom_notifier_t;
 
@@ -274,7 +277,7 @@ dap_chain_t * dap_chain_find_by_id(dap_chain_net_id_t a_chain_net_id,dap_chain_i
 dap_chain_t *dap_chain_load_from_cfg(const char *a_chain_net_name, dap_chain_net_id_t a_chain_net_id, const char *a_chain_cfg_name);
 
 void dap_chain_delete(dap_chain_t * a_chain);
-void dap_chain_add_callback_notify(dap_chain_t * a_chain, dap_chain_callback_notify_t a_callback, void * a_arg);
+void dap_chain_add_callback_notify(dap_chain_t *a_chain, dap_chain_callback_notify_t a_callback, dap_proc_thread_t *a_thread, void *a_arg);
 void dap_chain_atom_notify(dap_chain_cell_t *a_chain_cell,  dap_hash_fast_t *a_hash, const uint8_t *a_atom, size_t a_atom_size);
 void dap_chain_atom_add_from_threshold(dap_chain_t *a_chain);
 dap_chain_atom_ptr_t dap_chain_get_atom_by_hash(dap_chain_t * a_chain, dap_chain_hash_fast_t * a_atom_hash, size_t * a_atom_size);
diff --git a/modules/chain/tests/dap_chain_ledger_tests.c b/modules/chain/tests/dap_chain_ledger_tests.c
index 2dd5bfa8320b2d4464b8b748d2efc2ec0901852c..1e2a84476aadbf418da3b219a4d5418651019368 100644
--- a/modules/chain/tests/dap_chain_ledger_tests.c
+++ b/modules/chain/tests/dap_chain_ledger_tests.c
@@ -351,7 +351,7 @@ int dap_ledger_test_create_reward_decree(dap_chain_t *a_chain, dap_chain_net_id_
     dap_hash_fast_t l_decree_hash = {};
     dap_hash_fast(l_decree, l_decree_size, &l_decree_hash);
     // a_chain->callback_atom_add();
-    dap_assert_PIF(dap_chain_net_decree_apply(&l_decree_hash, l_decree, a_chain)==0, "Decree applying:");
+    dap_assert_PIF(dap_chain_net_decree_apply(&l_decree_hash, l_decree, a_chain, false)==0, "Decree applying:");
     return 0;
 }
 
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 5dcf39ce43476b5d7cfbb044f9d09d58f87b382d..66822232bd32e9e6f040a1d66de7d7b5900d516b 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
@@ -1124,7 +1124,6 @@ static bool s_grace_period_finish(dap_chain_net_srv_grace_usage_t *a_grace_item)
         }
 
         // make receipt or tx
-        char *l_receipt_hash_str;
         dap_chain_datum_tx_receipt_t *l_receipt = NULL;
         if (l_grace->usage->receipt_next){
             l_receipt = l_grace->usage->receipt_next;
@@ -1158,8 +1157,7 @@ static bool s_grace_period_finish(dap_chain_net_srv_grace_usage_t *a_grace_item)
             log_it(L_WARNING, "Tx already in chain, but receipt is not signed by client. Finish grace and wait receipt sign responce.");
             RET_WITH_DEL_A_GRACE(DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_RECEIPT_NO_SIGN);
         }
-        dap_get_data_hash_str_static(l_receipt, l_receipt_size, l_receipt_hash_str);
-        dap_global_db_set(SRV_RECEIPTS_GDB_GROUP, l_receipt_hash_str, l_receipt, l_receipt_size, false, NULL, NULL);
+        dap_global_db_set(SRV_RECEIPTS_GDB_GROUP, dap_get_data_hash_str(l_receipt, l_receipt_size).s, l_receipt, l_receipt_size, false, NULL, NULL);
             // Form input transaction
         char *l_hash_str = dap_hash_fast_to_str_new(&l_grace->usage->tx_cond_hash);
         log_it(L_NOTICE, "Trying create input tx cond from tx %s with active receipt", l_hash_str);
@@ -1447,9 +1445,7 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg)
         }
 
         // Store receipt if any problems with transactions
-        char *l_receipt_hash_str;
-        dap_get_data_hash_str_static(l_receipt, l_receipt_size, l_receipt_hash_str);
-        dap_global_db_set(SRV_RECEIPTS_GDB_GROUP, l_receipt_hash_str, l_receipt, l_receipt_size, false, NULL, NULL);
+        dap_global_db_set(SRV_RECEIPTS_GDB_GROUP, dap_get_data_hash_str(l_receipt, l_receipt_size).s, l_receipt, l_receipt_size, false, NULL, NULL);
         size_t l_success_size;
         if (!l_usage->is_grace) {
             // Form input transaction
diff --git a/modules/channel/chain-net/dap_stream_ch_chain_net.c b/modules/channel/chain-net/dap_stream_ch_chain_net.c
index fe4c18c8626843aee823fb25758b151e16a0159a..ec9fffdf12fe254efea6d432fde89a440ddf0020 100644
--- a/modules/channel/chain-net/dap_stream_ch_chain_net.c
+++ b/modules/channel/chain-net/dap_stream_ch_chain_net.c
@@ -113,17 +113,12 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void* a_arg)
     dap_stream_ch_chain_net_t * l_ch_chain_net = DAP_STREAM_CH_CHAIN_NET(a_ch);
     if(l_ch_chain_net) {
         dap_stream_ch_pkt_t *l_ch_pkt = (dap_stream_ch_pkt_t *)a_arg;
-        if (l_ch_pkt->hdr.type == DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_TEST) {
-            char *l_data_hash_str;
-            dap_get_data_hash_str_static(l_ch_pkt->data, l_ch_pkt->hdr.data_size, l_data_hash_str);
-            log_it(L_ATT, "Receive test data packet with hash %s", l_data_hash_str);
-            return false;
-        }
-        if (l_ch_pkt->hdr.data_size < sizeof(dap_stream_ch_chain_net_pkt_t)) {
-            log_it(L_WARNING, "Too small stream channel N packet size %u (header size %zu)",
-                                    l_ch_pkt->hdr.data_size, sizeof(dap_stream_ch_chain_net_pkt_t));
-            return false;
-        }
+        if (l_ch_pkt->hdr.type == DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_TEST)
+            return log_it(L_ATT, "Receive test data packet with hash %s", 
+                                 dap_get_data_hash_str(l_ch_pkt->data, l_ch_pkt->hdr.data_size).s), false;
+        if (l_ch_pkt->hdr.data_size < sizeof(dap_stream_ch_chain_net_pkt_t))
+            return log_it(L_WARNING, "Too small stream channel N packet size %u (header size %zu)",
+                                    l_ch_pkt->hdr.data_size, sizeof(dap_stream_ch_chain_net_pkt_t)), false;
         dap_stream_ch_chain_net_pkt_t *l_ch_chain_net_pkt = (dap_stream_ch_chain_net_pkt_t *)l_ch_pkt->data;
         if ((uint32_t)l_ch_chain_net_pkt->hdr.data_size + sizeof(dap_stream_ch_chain_net_pkt_t) > l_ch_pkt->hdr.data_size) {
             log_it(L_WARNING, "Too small stream channel N packet size %u (expected at least %zu)",
diff --git a/modules/common/dap_chain_datum_decree.c b/modules/common/dap_chain_datum_decree.c
index 5ef31fc6f91a9283bf35fcbbb5eb96abecc7b0d1..467d98c872e104cdd1e7229307f1a27e1b09600f 100644
--- a/modules/common/dap_chain_datum_decree.c
+++ b/modules/common/dap_chain_datum_decree.c
@@ -200,9 +200,7 @@ void dap_chain_datum_decree_dump_json(json_object *a_json_out, dap_chain_datum_d
             }
             dap_pkey_t *l_owner_pkey = /*DAP_NEW_STACK_SIZE(dap_pkey_t, l_tsd->size);
             memcpy(l_owner_pkey, l_tsd->data, l_tsd->size);*/ _dap_tsd_get_object(l_tsd, dap_pkey_t);
-            char *l_owner_pkey_str;
-            dap_get_data_hash_str_static(l_owner_pkey->pkey, l_owner_pkey->header.size, l_owner_pkey_str);
-            json_object_object_add(a_json_out, "Owner fingerprint", json_object_new_string(l_owner_pkey_str));
+            json_object_object_add(a_json_out, "Owner fingerprint", json_object_new_string(dap_get_data_hash_str(l_owner_pkey->pkey, l_owner_pkey->header.size).s));
             break;
         case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER:
             if (l_tsd->size > sizeof(uint256_t)){
diff --git a/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c b/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c
index b708d9d05db22af9ce2f1acdcaaae2d72cd6f7dc..c8523c0bd1a2e785214f3b5b69175514d6b28504 100644
--- a/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c
+++ b/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c
@@ -57,24 +57,20 @@ typedef struct dap_chain_cs_dag_poa_presign_callback{
     void *arg;
 } dap_chain_cs_dag_poa_presign_callback_t;
 
-struct round_timer_arg {
+typedef struct dap_chain_cs_dag_poa_round_item {
+    dap_chain_hash_fast_t datum_hash;
     dap_chain_cs_dag_t *dag;
-    uint64_t round_id;
     UT_hash_handle hh;
-};
+} dap_chain_cs_dag_poa_round_item_t;
 
 typedef struct dap_chain_cs_dag_poa_pvt {
     pthread_rwlock_t rounds_rwlock;
-    struct round_timer_arg *active_rounds;
-    dap_cert_t * events_sign_cert;
-    dap_cert_t ** auth_certs;
-    char * auth_certs_prefix;
-    uint16_t auth_certs_count;
-    uint16_t auth_certs_count_verify; // Number of signatures, needed for event verification
-    bool auto_confirmation;
-    bool auto_round_complete;
-    uint32_t confirmations_timeout; // wait signs over min value (auth_certs_count_verify)
-    uint32_t wait_sync_before_complete;
+    dap_chain_cs_dag_poa_round_item_t *event_items;
+    dap_cert_t *events_sign_cert, **auth_certs;
+    char *auth_certs_prefix;
+    uint16_t auth_certs_count, auth_certs_count_verify; // Number of signatures, needed for event verification
+    bool auto_confirmation, auto_round_complete;
+    uint32_t confirmations_timeout, wait_sync_before_complete;
     dap_chain_cs_dag_poa_presign_callback_t *callback_pre_sign;
     dap_interval_timer_t mempool_timer;
 } dap_chain_cs_dag_poa_pvt_t;
@@ -83,23 +79,21 @@ typedef struct dap_chain_cs_dag_poa_pvt {
 
 static void s_callback_delete(dap_chain_cs_dag_t * a_dag);
 static int s_callback_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg);
-static void s_poa_round_clean(void *a_arg);
 static int s_callback_created(dap_chain_t * a_chain, dap_config_t *a_chain_cfg);
 static int s_callback_event_verify(dap_chain_cs_dag_t *a_dag, dap_chain_cs_dag_event_t *a_dag_event, dap_hash_fast_t *a_event_hash);
 static dap_chain_cs_dag_event_t * s_callback_event_create(dap_chain_cs_dag_t * a_dag, dap_chain_datum_t * a_datum,
                                                           dap_chain_hash_fast_t * a_hashes, size_t a_hashes_count, size_t* a_event_size);
-static bool s_callback_round_event_to_chain(struct round_timer_arg *a_arg);
+static bool s_callback_round_event_to_chain(dap_chain_cs_dag_poa_round_item_t *a_arg);
 static int s_callback_event_round_sync(dap_chain_cs_dag_t * a_dag, const char a_op_code, const char *a_group,
                                         const char *a_key, const void *a_value, const size_t a_value_size);
 static bool s_round_event_ready_minimum_check(dap_chain_cs_dag_t *a_dag, dap_chain_cs_dag_event_t *a_event,
                                               size_t a_event_size, char *a_event_hash_hex_str);
-static void s_round_event_cs_done(dap_chain_cs_dag_t * a_dag, uint64_t a_round_id);
+static void s_round_event_cs_done(dap_chain_cs_dag_poa_round_item_t *a_event_item);
 
 // CLI commands
 static int s_cli_dag_poa(int argc, char ** argv, void **a_str_reply);
 
 static bool s_seed_mode = false;
-static dap_interval_timer_t s_poa_round_timer = NULL;
 static bool s_debug_more = false;
 
 /**
@@ -292,8 +286,13 @@ static int s_cli_dag_poa(int argc, char ** argv, void **a_str_reply)
                                     l_poa_pvt->events_sign_cert->name, l_event_new_hash_base58_str);
                         }
                         ret = 0;
-                        if (l_event_is_ready && l_poa_pvt->auto_round_complete) // cs done (minimum signs & verify passed)
-                            s_round_event_cs_done(l_dag, l_event->header.round_id);
+                        if (l_event_is_ready && l_poa_pvt->auto_round_complete) { // cs done (minimum signs & verify passed) 
+                            dap_chain_cs_dag_poa_round_item_t l_event_item = {
+                                .datum_hash = l_round_item->round_info.datum_hash,
+                                .dag = l_dag
+                            };
+                            s_round_event_cs_done(&l_event_item);
+                        }
                     } else {
                         if(!dap_strcmp(l_hash_out_type, "hex")) {
                             dap_cli_server_cmd_set_reply_text(a_str_reply,
@@ -396,15 +395,13 @@ static int s_callback_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg)
     log_it(L_NOTICE,"Initialized DAG-PoA consensus with %u/%u minimum consensus",l_poa_pvt->auth_certs_count,l_poa_pvt->auth_certs_count_verify);
     l_dag->chain->callback_created = s_callback_created;
 
-    if (!l_dag->is_add_directly && l_poa_pvt->auto_round_complete) {
-        dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id);
-        dap_chain_node_role_t l_role = dap_chain_net_get_role(l_net);
-        if (l_role.enums == NODE_ROLE_ROOT_MASTER || l_role.enums == NODE_ROLE_ROOT) {
-            if (!s_poa_round_timer) {
-                s_poa_round_timer = dap_interval_timer_create(600 * 1000, s_poa_round_clean, a_chain);
-                log_it(L_MSG, "DAG-PoA: Round timer is started");
-            }
-            DAP_CHAIN_PVT(a_chain)->cs_started = true;
+    if ( !l_dag->is_add_directly && l_poa_pvt->auto_round_complete ) {
+        switch ( dap_chain_net_get_role(dap_chain_net_by_id(a_chain->net_id)).enums ) {
+            case NODE_ROLE_ROOT_MASTER:
+            case NODE_ROLE_ROOT:
+                DAP_CHAIN_PVT(a_chain)->cs_started = true;
+            default:
+                break;
         }
     }
 
@@ -420,69 +417,6 @@ static int s_callback_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg)
     return 0;
 }
 
-/**
- * @brief s_poa_round_check_callback_load_round
- * @param a_global_db_context
- * @param a_rc
- * @param a_group
- * @param a_key
- * @param a_values_total
- * @param a_values_shift
- * @param a_values_count
- * @param a_values
- * @param a_arg
- */
-static bool s_poa_round_check_callback_round_clean(dap_global_db_instance_t *a_dbi,
-                                                   int a_rc, const char *a_group,
-                                                   const size_t a_values_total, const size_t a_values_count,
-                                                   dap_global_db_obj_t *a_values, void *a_arg)
-{
-    dap_chain_cs_dag_t *l_dag = (dap_chain_cs_dag_t *)a_arg;
-    dap_chain_cs_dag_poa_t *l_poa = DAP_CHAIN_CS_DAG_POA(l_dag);
-    dap_chain_cs_dag_poa_pvt_t *l_poa_pvt = PVT(l_poa);
-
-    if (a_values_count) {
-        for (size_t i = 0; i < a_values_count; i++) {
-            if (!strcmp(DAG_ROUND_CURRENT_KEY, a_values[i].key))
-                continue;
-            if (a_values[i].value_len <= sizeof(dap_chain_cs_dag_event_round_item_t) + sizeof(dap_chain_cs_dag_event_t)) {
-                log_it(L_WARNING, "Too small round item in DAG PoA rounds GDB group");
-                dap_global_db_del_sync(a_group, a_values[i].key);
-                continue;
-            }
-            dap_chain_cs_dag_event_round_item_t *l_event_round_item = (dap_chain_cs_dag_event_round_item_t *)a_values[i].value;
-            uint64_t l_time_diff = dap_nanotime_now() - l_event_round_item->round_info.ts_update;
-            uint64_t l_timeuot = dap_nanotime_from_sec(l_poa_pvt->confirmations_timeout + l_poa_pvt->wait_sync_before_complete + 10);
-            uint64_t l_round_id = ((dap_chain_cs_dag_event_t *)l_event_round_item->event_n_signs)->header.round_id;
-            if (((int64_t)l_time_diff > 0 && l_time_diff > l_timeuot) || l_round_id <= l_dag->round_completed) {
-                pthread_rwlock_rdlock(&l_poa_pvt->rounds_rwlock);
-                struct round_timer_arg *l_arg = NULL;
-                HASH_FIND(hh, l_poa_pvt->active_rounds, &l_round_id, sizeof(uint64_t), l_arg);
-                pthread_rwlock_unlock(&l_poa_pvt->rounds_rwlock);
-                if (l_arg) {
-                    log_it(L_INFO, "Event %s is from currently active round [id %"DAP_UINT64_FORMAT_U"]", a_values[i].key, l_round_id);
-                    continue;
-                }
-                dap_global_db_del_sync(a_group, a_values[i].key);
-                log_it(L_DEBUG, "DAG-PoA: Remove event %s from round %"DAP_UINT64_FORMAT_U" %s.",
-                       a_values[i].key, l_round_id, l_time_diff > l_timeuot ? "by timer" : "owing to round completion");
-            }
-        }
-    }
-    return true;
-}
-
-/**
- * @brief Timer callback for round check
- * @param a_chain Chain object
- * @return Always true
- */
-static void s_poa_round_clean(void *a_arg)
-{
-    dap_chain_cs_dag_t *l_dag = DAP_CHAIN_CS_DAG((dap_chain_t *)a_arg);
-    dap_global_db_get_all(l_dag->gdb_group_events_round_new, 0, s_poa_round_check_callback_round_clean, l_dag);
-}
-
 static bool s_round_event_ready_minimum_check(dap_chain_cs_dag_t *a_dag, dap_chain_cs_dag_event_t *a_event,
                                               size_t a_event_size, char * a_event_hash_hex_str)
 {
@@ -601,58 +535,78 @@ static bool s_callback_round_event_to_chain_callback_get_round_item(dap_global_d
 {
     if (a_rc != DAP_GLOBAL_DB_RC_SUCCESS) 
         return false;
-    struct round_timer_arg *l_arg = (struct round_timer_arg *)a_arg;
+    dap_chain_cs_dag_poa_round_item_t *l_arg = (dap_chain_cs_dag_poa_round_item_t*)a_arg;
     dap_chain_cs_dag_t *l_dag = l_arg->dag;
-    uint64_t l_round_id = l_arg->round_id;
     dap_chain_cs_dag_poa_pvt_t *l_poa_pvt = PVT(DAP_CHAIN_CS_DAG_POA(l_dag));
     pthread_rwlock_wrlock(&l_poa_pvt->rounds_rwlock);
-    HASH_DEL(l_poa_pvt->active_rounds, l_arg);
+    HASH_DEL(l_poa_pvt->event_items, l_arg);
     pthread_rwlock_unlock(&l_poa_pvt->rounds_rwlock);
-    DAP_DELETE(a_arg);
     uint16_t l_max_signs_count = 0;
     dap_list_t *l_dups_list = NULL;
-    for (size_t i = 0; i < a_values_count; i++) {
+    size_t i, e, k;
+    const char *l_complete_keys[a_values_count], *l_expired_keys[a_values_count];
+    for (i = 0, e = 0, k = 0; i < a_values_count; i++) {
         if (!strcmp(DAG_ROUND_CURRENT_KEY, a_values[i].key))
             continue;
-        dap_chain_cs_dag_event_round_item_t *l_round_item = (dap_chain_cs_dag_event_round_item_t *)a_values[i].value;
+        if (a_values[i].value_len <= sizeof(dap_chain_cs_dag_event_round_item_t) + sizeof(dap_chain_cs_dag_event_t)) {
+            log_it(L_WARNING, "Incorrect round item size, dump it");
+            dap_global_db_del_sync(a_group, a_values[i].key);
+            continue;
+        }
+        dap_chain_cs_dag_event_round_item_t *l_round_item = (dap_chain_cs_dag_event_round_item_t*)a_values[i].value;
         dap_chain_cs_dag_event_t *l_event = (dap_chain_cs_dag_event_t *)l_round_item->event_n_signs;
-        if (l_event->header.round_id == l_round_id &&
-                l_round_item->round_info.reject_count < l_poa_pvt->auth_certs_count_verify) {
+        if ( dap_hash_fast_compare( &l_arg->datum_hash, &l_round_item->round_info.datum_hash )
+            && l_round_item->round_info.reject_count < l_poa_pvt->auth_certs_count_verify)
+        {
             l_dups_list = dap_list_append(l_dups_list, l_round_item);
             if (l_event->header.signs_count > l_max_signs_count)
                 l_max_signs_count = l_event->header.signs_count;
+            l_complete_keys[k++] = a_values[i].key;
+        }
+        else if ( dap_nanotime_from_sec(l_poa_pvt->wait_sync_before_complete + l_poa_pvt->confirmations_timeout + 10)
+                 < dap_nanotime_now() - l_round_item->round_info.ts_update )
+        {
+            l_expired_keys[e++] = a_values[i].key;
         }
     }
     dap_chain_cs_dag_event_round_item_t *l_chosen_item = s_round_event_choose_dup(l_dups_list, l_max_signs_count);
+    dap_list_free(l_dups_list);
+    char l_datum_hash_str[DAP_HASH_FAST_STR_SIZE];
+    dap_hash_fast_to_str(&l_arg->datum_hash, l_datum_hash_str, sizeof(l_datum_hash_str));
     if (l_chosen_item) {
         size_t l_event_size = l_chosen_item->event_size;
         dap_chain_cs_dag_event_t *l_new_atom = (dap_chain_cs_dag_event_t *)l_chosen_item->event_n_signs;
-        char *l_event_hash_hex_str;
-        dap_get_data_hash_str_static(l_new_atom, l_event_size, l_event_hash_hex_str);
+        dap_hash_fast_t l_atom_hash;
+        dap_hash_fast(l_new_atom, l_event_size, &l_atom_hash);
+        char l_event_hash_hex_str[DAP_HASH_FAST_STR_SIZE]; dap_hash_fast_to_str(&l_atom_hash, l_event_hash_hex_str, DAP_HASH_FAST_STR_SIZE);
         dap_chain_datum_t *l_datum = dap_chain_cs_dag_event_get_datum(l_new_atom, l_event_size);
-        l_dag->round_completed = dap_max(l_new_atom->header.round_id, l_dag->round_current);
         int l_verify_datum = dap_chain_net_verify_datum_for_add(l_dag->chain, l_datum, &l_chosen_item->round_info.datum_hash);
         if (!l_verify_datum) {
-            dap_hash_fast_t l_atom_hash = {};
-            dap_hash_fast(l_new_atom, l_event_size, &l_atom_hash);
             dap_chain_atom_verify_res_t l_res = l_dag->chain->callback_atom_add(l_dag->chain, l_new_atom, l_event_size, &l_atom_hash, true);
-            if (l_res == ATOM_ACCEPT)
-                s_poa_round_clean(l_dag->chain);
-            log_it(L_INFO, "Event %s from round %"DAP_UINT64_FORMAT_U" %s",
-                   l_event_hash_hex_str, l_round_id, dap_chain_atom_verify_res_str[l_res]);
+            if (l_res == ATOM_ACCEPT) {
+                for (; k; --k) {
+                    log_it(L_INFO, "Remove event %s with datum %s, round complete", l_complete_keys[k - 1], l_datum_hash_str);
+                    dap_global_db_del_sync(a_group, l_complete_keys[k - 1]);
+                }
+                for (; e; --e) {
+                    log_it(L_INFO, "Event %s with datum %s has expired, dump it", l_expired_keys[e - 1], l_datum_hash_str);
+                    dap_global_db_del_sync(a_group,  l_expired_keys[e - 1]);
+                }
+            }
+            log_it(L_INFO, "Event %s with datum %s is %s",
+                           l_event_hash_hex_str, l_datum_hash_str, dap_chain_atom_verify_res_str[l_res]);
         } else {
-            char l_datum_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
-            dap_chain_hash_fast_to_str(&l_chosen_item->round_info.datum_hash, l_datum_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE);
-            log_it(L_INFO, "Event %s from round %"DAP_UINT64_FORMAT_U" not added into chain, because the inner datum %s doesn't pass verification (%s)",
-                   l_event_hash_hex_str, l_round_id, l_datum_hash_str, dap_chain_net_verify_datum_err_code_to_str(l_datum, l_verify_datum));
+            log_it(L_ERROR, "Event %s is not chained: datum %s doesn't pass verification, error \"%s\"",
+                            l_event_hash_hex_str, l_datum_hash_str, dap_chain_net_verify_datum_err_code_to_str(l_datum, l_verify_datum));
+            for (; k; --k) {
+                log_it(L_INFO, "Remove event %s with unverified datum %s", l_complete_keys[k - 1], l_datum_hash_str);
+                dap_global_db_del_sync(a_group, l_complete_keys[k - 1]);
+            }
         }
-    } else { /* !l_chosen_item */
-        l_dag->round_completed = l_dag->round_current;
-        log_it(L_WARNING, "No candidates for round id %"DAP_UINT64_FORMAT_U, l_round_id);
-
-    }
-    dap_list_free(l_dups_list);
-    return true;
+    } else /* !l_chosen_item */
+        log_it(L_WARNING, "No valid candidates to wrap datum %s in current round #%"DAP_UINT64_FORMAT_U"",
+                          l_datum_hash_str, l_dag->round_id);
+    return DAP_DELETE(l_arg), true;
 }
 
 /**
@@ -660,39 +614,25 @@ static bool s_callback_round_event_to_chain_callback_get_round_item(dap_global_d
  * @param a_callback_arg
  * @return
  */
-static bool s_callback_round_event_to_chain(struct round_timer_arg *a_callback_arg)
+static bool s_callback_round_event_to_chain(dap_chain_cs_dag_poa_round_item_t *a_callback_arg)
 {
-    dap_chain_cs_dag_t *l_dag = a_callback_arg->dag;
-    dap_global_db_get_all(l_dag->gdb_group_events_round_new, 0, s_callback_round_event_to_chain_callback_get_round_item, a_callback_arg);
-    return false;
+    return dap_global_db_get_all(a_callback_arg->dag->gdb_group_events_round_new, 0, s_callback_round_event_to_chain_callback_get_round_item, a_callback_arg),
+        false;
 }
 
-static void s_round_event_cs_done(dap_chain_cs_dag_t * a_dag, uint64_t a_round_id)
+static void s_round_event_cs_done(dap_chain_cs_dag_poa_round_item_t *a_event_item)
 {
-    dap_chain_cs_dag_poa_t *l_poa = DAP_CHAIN_CS_DAG_POA(a_dag);
-    dap_chain_cs_dag_poa_pvt_t *l_poa_pvt = PVT(l_poa);
-    struct round_timer_arg *l_callback_arg = NULL;
+    dap_chain_cs_dag_poa_pvt_t *l_poa_pvt = PVT( DAP_CHAIN_CS_DAG_POA(a_event_item->dag) );
+    dap_chain_cs_dag_poa_round_item_t *l_event_item = NULL;
     pthread_rwlock_wrlock(&l_poa_pvt->rounds_rwlock);
-    HASH_FIND(hh, l_poa_pvt->active_rounds, &a_round_id, sizeof(uint64_t), l_callback_arg);
-    if (!l_callback_arg) {
-        l_callback_arg = DAP_NEW_Z(struct round_timer_arg);
-        if (!l_callback_arg) {
-            pthread_rwlock_unlock(&l_poa_pvt->rounds_rwlock);
-            log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-            return;
-        }
-        l_callback_arg->dag = a_dag;
-        l_callback_arg->round_id = a_round_id;
-        HASH_ADD(hh, l_poa_pvt->active_rounds, round_id, sizeof(uint64_t), l_callback_arg);
-        // Placement into chain by confirmation timer
-        if (!dap_timerfd_start(PVT(l_poa)->confirmations_timeout * 1000, (dap_timerfd_callback_t)s_callback_round_event_to_chain, l_callback_arg)) {
-            HASH_DEL(l_poa_pvt->active_rounds, l_callback_arg);
-            pthread_rwlock_unlock(&l_poa_pvt->rounds_rwlock);
-            DAP_DELETE(l_callback_arg);
-            log_it(L_ERROR,"Can't run timer for round ID %"DAP_UINT64_FORMAT_U, a_round_id);
-            return;
-        }
-        log_it(L_NOTICE,"Run timer for %d sec for round ID %"DAP_UINT64_FORMAT_U, PVT(l_poa)->confirmations_timeout, a_round_id);
+    HASH_FIND(hh, l_poa_pvt->event_items, &a_event_item->datum_hash, sizeof(dap_hash_fast_t), l_event_item);
+    if (!l_event_item) {
+        l_event_item = DAP_DUP(a_event_item);
+        if ( !dap_timerfd_start(l_poa_pvt->confirmations_timeout * 1000, (dap_timerfd_callback_t)s_callback_round_event_to_chain, l_event_item) )
+            return DAP_DELETE(l_event_item), pthread_rwlock_unlock(&l_poa_pvt->rounds_rwlock), log_it(L_CRITICAL, "Timer creation failed");
+        HASH_ADD(hh, l_poa_pvt->event_items, datum_hash, sizeof(dap_hash_fast_t), l_event_item);
+        log_it(L_INFO, "Confirmation timer for datum %s started [%d s]",
+                       dap_chain_hash_fast_to_str_static(&l_event_item->datum_hash), l_poa_pvt->confirmations_timeout);
     }
     pthread_rwlock_unlock(&l_poa_pvt->rounds_rwlock);
 }
@@ -709,22 +649,25 @@ static bool s_callback_sync_all_on_start(dap_global_db_instance_t *a_dbi, int a_
 
 static void s_round_changes_notify(dap_store_obj_t *a_obj, void *a_arg)
 {
-    dap_chain_cs_dag_t *l_dag = (dap_chain_cs_dag_t *)a_arg;
-    assert(l_dag);
+    assert(a_arg);
+    dap_chain_cs_dag_t *l_dag = (dap_chain_cs_dag_t*)a_arg;
     dap_chain_net_t *l_net = dap_chain_net_by_id(l_dag->chain->net_id);
-    log_it(L_DEBUG, "%s.%s: op_code='%c' group=\"%s\" key=\"%s\" value_size=%zu",
-        l_net->pub.name, l_dag->chain->name, dap_store_obj_get_type(a_obj), a_obj->group, a_obj->key, a_obj->value_len);
-    if (dap_store_obj_get_type(a_obj) == DAP_GLOBAL_DB_OPTYPE_ADD) {
-        if (dap_strcmp(a_obj->key, DAG_ROUND_CURRENT_KEY))  // check key for round increment, if no than process event
-            s_callback_event_round_sync(l_dag, dap_store_obj_get_type(a_obj), a_obj->group, a_obj->key, a_obj->value, a_obj->value_len);
-        else
-            log_it(L_INFO, "Global round ID: %lu", *(uint64_t*)a_obj->value);
+    dap_global_db_optype_t l_type = dap_store_obj_get_type(a_obj);
+    log_it(L_DEBUG, "%s.%s: op_code '%c', group \"%s\", key \"%s\", value_size %zu",
+        l_net->pub.name, l_dag->chain->name, l_type, a_obj->group, a_obj->key, a_obj->value_len);
+    if ( !dap_strcmp(a_obj->key, DAG_ROUND_CURRENT_KEY) )
+        return;
+    switch ( l_type ) {
+    case DAP_GLOBAL_DB_OPTYPE_ADD:
+        s_callback_event_round_sync(l_dag, l_type, a_obj->group, a_obj->key, a_obj->value, a_obj->value_len);
+    default:
+        break;
     }
 }
 
 static void s_timer_process_callback(void *a_arg)
 {
-    dap_chain_node_mempool_process_all((dap_chain_t *)a_arg, false);
+    dap_chain_node_mempool_process_all( (dap_chain_t*)a_arg, false );
 }
 
 /**
@@ -756,19 +699,15 @@ static int s_callback_created(dap_chain_t * a_chain, dap_config_t *a_chain_net_c
     dap_global_db_cluster_add_notify_callback(l_dag_cluster, s_round_changes_notify, l_dag);
     dap_chain_net_add_auth_nodes_to_cluster(l_net, l_dag_cluster);
     dap_link_manager_add_net_associate(l_net->pub.id.uint64, l_dag_cluster->links_cluster);
-
-    byte_t *l_current_round = dap_global_db_get_sync(l_dag->gdb_group_events_round_new, DAG_ROUND_CURRENT_KEY, NULL, NULL, NULL);
-    l_dag->round_current = l_current_round ? *(uint64_t*)l_current_round : 0;
-    DAP_DELETE(l_current_round);
-    log_it(L_INFO, "Current round id %"DAP_UINT64_FORMAT_U, l_dag->round_current);
-
+    l_dag->round_id = 0;
     PVT(l_poa)->mempool_timer = dap_interval_timer_create(15000, s_timer_process_callback, a_chain);
 
-    dap_chain_node_role_t l_role = dap_chain_net_get_role(l_net);
-    if (l_role.enums == NODE_ROLE_ROOT_MASTER || l_role.enums == NODE_ROLE_ROOT) {
-        l_dag->round_completed = l_dag->round_current++;
-        log_it(L_MSG, "Round complete ID %"DAP_UINT64_FORMAT_U", current ID %"DAP_UINT64_FORMAT_U, l_dag->round_completed, l_dag->round_current);
-        dap_global_db_get_all(l_dag->gdb_group_events_round_new, 0, s_callback_sync_all_on_start, l_dag);
+    switch ( dap_chain_net_get_role(l_net).enums ) {
+        case NODE_ROLE_ROOT_MASTER:
+        case NODE_ROLE_ROOT:
+            dap_global_db_get_all(l_dag->gdb_group_events_round_new, 0, s_callback_sync_all_on_start, l_dag);
+        default:
+            break;
     }
     return 0;
 }
@@ -780,7 +719,6 @@ static int s_callback_created(dap_chain_t * a_chain, dap_config_t *a_chain_net_c
  */
 static void s_callback_delete(dap_chain_cs_dag_t * a_dag)
 {
-    dap_interval_timer_delete(s_poa_round_timer);
     dap_chain_cs_dag_poa_t * l_poa = DAP_CHAIN_CS_DAG_POA ( a_dag );
 
     if ( l_poa->_pvt ) {
@@ -819,26 +757,19 @@ static dap_chain_cs_dag_event_t * s_callback_event_create(dap_chain_cs_dag_t * a
                                                           dap_chain_hash_fast_t * a_hashes, size_t a_hashes_count, size_t* a_event_size)
 {
     dap_return_val_if_fail(a_dag && a_dag->chain && DAP_CHAIN_CS_DAG_POA(a_dag), NULL);
-    dap_chain_cs_dag_poa_t * l_poa = DAP_CHAIN_CS_DAG_POA(a_dag);
-    if ( PVT(l_poa)->events_sign_cert == NULL){
+    dap_chain_cs_dag_poa_t *l_poa = DAP_CHAIN_CS_DAG_POA(a_dag);
+    if ( !PVT(l_poa)->events_sign_cert )
         log_it(L_ERROR, "Can't sign event with events_sign_cert in [dag-poa] section");
-        return  NULL;
-    }
-    if ( s_seed_mode || (a_hashes && a_hashes_count) ){
+    else if ( s_seed_mode || (a_hashes && a_hashes_count) ) {
         if ( !PVT(l_poa)->callback_pre_sign || !PVT(l_poa)->callback_pre_sign->callback) {
-            dap_chain_cs_dag_event_t * l_event = dap_chain_cs_dag_event_new(a_dag->chain->id, a_dag->chain->cells->id, a_dag->round_current,
+            return dap_chain_cs_dag_event_new(a_dag->chain->id, a_dag->chain->cells->id, a_dag->round_id,
                                                                             a_datum, PVT(l_poa)->events_sign_cert->enc_key,
                                                                             a_hashes, a_hashes_count, a_event_size);
-            return l_event;
         } else {
-            dap_chain_cs_dag_event_t *l_event = dap_chain_cs_dag_event_new(a_dag->chain->id, a_dag->chain->cells->id, a_dag->round_current,
-                                                                           a_datum, NULL,
-                                                                           a_hashes, a_hashes_count, a_event_size);
-            int ret = PVT(l_poa)->callback_pre_sign->callback(a_dag->chain, l_event, *a_event_size, PVT(l_poa)->callback_pre_sign->arg);
-            if (ret) {
-                DAP_DELETE(l_event);
-                return NULL;
-            }
+            dap_chain_cs_dag_event_t *l_event = dap_chain_cs_dag_event_new(a_dag->chain->id, a_dag->chain->cells->id, a_dag->round_id,
+                                                                           a_datum, NULL, a_hashes, a_hashes_count, a_event_size);
+            if ( PVT(l_poa)->callback_pre_sign->callback(a_dag->chain, l_event, *a_event_size, PVT(l_poa)->callback_pre_sign->arg) )
+                return DAP_DELETE(l_event), NULL;
             *a_event_size = dap_chain_cs_dag_event_sign_add(&l_event, *a_event_size, PVT(l_poa)->events_sign_cert->enc_key);
             return l_event;
         }
@@ -849,11 +780,8 @@ static dap_chain_cs_dag_event_t * s_callback_event_create(dap_chain_cs_dag_t * a
 static int s_callback_event_round_sync(dap_chain_cs_dag_t * a_dag, const char a_op_code, const char *a_group,
                                         const char *a_key, const void *a_value, const size_t a_value_size)
 {
-    if (a_op_code != DAP_GLOBAL_DB_OPTYPE_ADD || !a_key || !a_value || !a_value_size)
-        return 0;
-
-    if (!strcmp(DAG_ROUND_CURRENT_KEY, a_key))
-        return 0;
+    dap_return_val_if_pass(a_op_code != DAP_GLOBAL_DB_OPTYPE_ADD || !a_key || !a_value
+                           || !a_value_size || !strcmp(DAG_ROUND_CURRENT_KEY, a_key), 0);
 
     dap_chain_cs_dag_poa_t * l_poa = DAP_CHAIN_CS_DAG_POA(a_dag);
     dap_chain_cs_dag_poa_pvt_t *l_poa_pvt = PVT(l_poa);
@@ -867,58 +795,36 @@ static int s_callback_event_round_sync(dap_chain_cs_dag_t * a_dag, const char a_
     dap_chain_cs_dag_event_round_item_t *l_round_item = (dap_chain_cs_dag_event_round_item_t *)a_value;
     size_t l_event_size = l_round_item->event_size;
     dap_chain_cs_dag_event_t *l_event = (dap_chain_cs_dag_event_t*)DAP_DUP_SIZE(l_round_item->event_n_signs, l_event_size);
-    if (!l_event) {
-        log_it(L_CRITICAL, "Memory allocation failed");
-        return -1;
-    }
-    if (l_event->header.round_id < a_dag->round_completed) {
-        struct round_timer_arg *l_round_active = NULL;
-        uint64_t l_round_id = l_event->header.round_id;
-        pthread_rwlock_wrlock(&l_poa_pvt->rounds_rwlock);
-        HASH_FIND(hh, l_poa_pvt->active_rounds, &l_round_id, sizeof(uint64_t), l_round_active);
-        pthread_rwlock_unlock(&l_poa_pvt->rounds_rwlock);
-        if (!l_round_active) {
-            log_it(L_DEBUG, "DAG event came from too old round [last complete id %"DAP_UINT64_FORMAT_U" > %"DAP_UINT64_FORMAT_U"], skip it",
-                   a_dag->round_completed, l_event->header.round_id);
-            DAP_DELETE(l_event);
-            return -2;
-        }
-    }
-    if (dap_chain_cs_dag_event_sign_exists(l_event, l_event_size, l_poa_pvt->events_sign_cert->enc_key)
-            || dap_chain_cs_dag_event_round_sign_exists(l_round_item, l_poa_pvt->events_sign_cert->enc_key)) {
-        // if my sign exists
-        if (l_poa_pvt->auto_round_complete &&
-                s_round_event_ready_minimum_check(a_dag, l_event, l_event_size, (char *)a_key))
-            // cs done (minimum signs & verify passed)
-            s_round_event_cs_done(a_dag, l_event->header.round_id);
-        DAP_DELETE(l_event);
-        return 0;
+    if (!l_event)
+        return log_it(L_CRITICAL, "Memory allocation failed"), -1;
+
+    if ( dap_chain_cs_dag_event_sign_exists(l_event, l_event_size, l_poa_pvt->events_sign_cert->enc_key)
+        || dap_chain_cs_dag_event_round_sign_exists(l_round_item, l_poa_pvt->events_sign_cert->enc_key)
+        && l_poa_pvt->auto_round_complete
+        && s_round_event_ready_minimum_check(a_dag, l_event, l_event_size, (char*)a_key) )
+    {
+        dap_chain_cs_dag_poa_round_item_t l_event_item = { .datum_hash = l_round_item->round_info.datum_hash, .dag = a_dag };
+        return DAP_DELETE(l_event), s_round_event_cs_done(&l_event_item), 0;
     }
 
     size_t l_event_size_new = 0;
     int ret = 0;
-    if (l_event->header.round_id > a_dag->round_current) {
-        log_it(L_DEBUG, "Refresh current round ID [%lu -> %lu]", a_dag->round_current, l_event->header.round_id);
-        a_dag->round_current = l_event->header.round_id;
-    }
-    if (!l_poa_pvt->callback_pre_sign || !l_poa_pvt->callback_pre_sign->callback ||
-             !(ret = l_poa_pvt->callback_pre_sign->callback(a_dag->chain, l_event, l_event_size,
-                                                      l_poa_pvt->callback_pre_sign->arg))) {
+    if ( !l_poa_pvt->callback_pre_sign || !l_poa_pvt->callback_pre_sign->callback
+        || !(ret = l_poa_pvt->callback_pre_sign->callback(a_dag->chain, l_event, l_event_size,
+                                                          l_poa_pvt->callback_pre_sign->arg)) )
+    {
         l_event_size_new = dap_chain_cs_dag_event_sign_add(&l_event, l_event_size, l_poa_pvt->events_sign_cert->enc_key);
-        //char *l_event_new_hash_hex_str;
-        //dap_get_data_hash_str_static(l_event, l_event_size_new, l_event_new_hash_hex_str);
-        dap_chain_cs_dag_event_gdb_set(a_dag, /*l_event_new_hash_hex_str*/ (char*)a_key, l_event, l_event_size_new, l_round_item);
+        dap_chain_cs_dag_event_gdb_set(a_dag, (char*)a_key, l_event, l_event_size_new, l_round_item);
     } else { // set sign for reject
         l_round_item = DAP_DUP_SIZE(a_value, a_value_size);
         if (dap_chain_cs_dag_event_round_sign_add(&l_round_item, a_value_size, l_poa_pvt->events_sign_cert->enc_key)) {
-            log_it(L_NOTICE,"Can't sign event %s, because sign rejected by pre_sign callback, ret code=%d", a_key, ret);
+            log_it(L_NOTICE,"Can't sign event %s, because sign rejected by pre_sign callback, ret code %d", a_key, ret);
             l_round_item->round_info.reject_count++;
-            dap_chain_cs_dag_event_gdb_set(a_dag, (char *)a_key, l_event, l_event_size, l_round_item);
+            dap_chain_cs_dag_event_gdb_set(a_dag, (char*)a_key, l_event, l_event_size, l_round_item);
         }
         DAP_DELETE(l_round_item);
     }
-    DAP_DELETE(l_event);
-    return 0;
+    return DAP_DELETE(l_event), ret;
 }
 
 /**
diff --git a/modules/consensus/esbocs/dap_chain_cs_esbocs.c b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
index 9ec843ca7105ac76258eb40e2b6e84c60f4aea18..75e8f9c05ef405b23d2c9254fc0e7dabaf83d648 100644
--- a/modules/consensus/esbocs/dap_chain_cs_esbocs.c
+++ b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
@@ -427,7 +427,6 @@ static void s_new_atom_notifier(void *a_arg, dap_chain_t *a_chain, dap_chain_cel
 {
     dap_chain_esbocs_session_t *l_session = a_arg;
     assert(l_session->chain == a_chain);
-    //pthread_mutex_lock(&l_session->mutex);
     dap_chain_hash_fast_t l_last_block_hash;
     dap_chain_get_atom_last_hash(l_session->chain, a_id, &l_last_block_hash);
     if (!dap_hash_fast_compare(&l_last_block_hash, &l_session->cur_round.last_block_hash) &&
@@ -435,7 +434,6 @@ static void s_new_atom_notifier(void *a_arg, dap_chain_t *a_chain, dap_chain_cel
         l_session->new_round_enqueued = true;
         s_session_round_new(l_session);
     }
-    //pthread_mutex_unlock(&l_session->mutex);
     if (!PVT(l_session->esbocs)->collecting_addr)
         return;
     dap_chain_esbocs_block_collect_t l_block_collect_params = (dap_chain_esbocs_block_collect_t){
@@ -593,9 +591,9 @@ static int s_callback_created(dap_chain_t *a_chain, dap_config_t *a_chain_net_cf
         log_it(L_ERROR, "This validator is not allowed to work in emergency mode. Use special decree to supply it");
         return -5;
     }
-    //pthread_mutex_init(&l_session->mutex, NULL);
-    dap_chain_add_callback_notify(a_chain, s_new_atom_notifier, l_session);
-    s_session_round_new(l_session);
+    dap_chain_add_callback_notify(a_chain, s_new_atom_notifier, l_session->proc_thread, l_session);
+    //s_session_round_new(l_session);
+    dap_proc_thread_callback_add(l_session->proc_thread, s_session_round_new, l_session);
 
     l_session->cs_timer = !dap_proc_thread_timer_add(l_session->proc_thread, s_session_proc_state, l_session, 1000);
     debug_if(l_esbocs_pvt->debug && l_session->cs_timer, L_MSG, "Consensus main timer is started");
@@ -789,7 +787,6 @@ static void s_callback_delete(dap_chain_cs_blocks_t *a_blocks)
         log_it(L_INFO, "No session found");
         return;
     }
-    //pthread_mutex_lock(&l_session->mutex);
     DL_DELETE(s_session_items, l_session);
     s_session_round_clear(l_session);
     dap_chain_esbocs_sync_item_t *l_sync_item, *l_sync_tmp;
@@ -803,8 +800,6 @@ static void s_callback_delete(dap_chain_cs_blocks_t *a_blocks)
         HASH_DEL(l_session->penalty, l_pen_item);
         DAP_DELETE(l_pen_item);
     }
-    //pthread_mutex_unlock(&l_session->mutex);
-    //pthread_mutex_destroy(&l_session->mutex);
     DAP_DEL_MULTY(l_session, a_blocks->_inheritor); // a_blocks->_inheritor - l_esbocs
 }
 
@@ -998,8 +993,9 @@ static void s_db_calc_sync_hash(dap_chain_esbocs_session_t *a_session)
     a_session->is_actual_hash = true;
 }
 
-static void s_session_send_startsync(dap_chain_esbocs_session_t *a_session)
+static void s_session_send_startsync(void *a_arg)
 {
+    dap_chain_esbocs_session_t *a_session = (dap_chain_esbocs_session_t*)a_arg;
     if (a_session->cur_round.sync_sent)
         return;     // Sync message already was sent
     dap_chain_hash_fast_t l_last_block_hash;
@@ -1029,16 +1025,6 @@ static void s_session_send_startsync(dap_chain_esbocs_session_t *a_session)
     a_session->cur_round.sync_sent = true;
 }
 
-static bool s_session_send_startsync_on_timer(void *a_arg)
-{
-    dap_chain_esbocs_session_t *l_session = a_arg;
-    //pthread_mutex_lock(&l_session->mutex);
-    s_session_send_startsync(l_session);
-    l_session->sync_timer = NULL;
-    //pthread_mutex_unlock(&l_session->mutex);
-    return false;
-}
-
 static void s_session_update_penalty(dap_chain_esbocs_session_t *a_session)
 {
     for (dap_list_t *it = a_session->cur_round.all_validators; it; it = it->next) {
@@ -1100,11 +1086,6 @@ static bool s_session_round_new(void *a_arg)
     s_session_round_clear(a_session);
     a_session->cur_round.id++;
     a_session->cur_round.sync_attempt++;
-
-    if (a_session->sync_timer) {
-        dap_timerfd_delete_mt(a_session->sync_timer->worker, a_session->sync_timer->esocket_uuid);
-        a_session->sync_timer = NULL;
-    }
     a_session->state = DAP_CHAIN_ESBOCS_SESSION_STATE_WAIT_START;
     a_session->ts_round_sync_start = 0;
     a_session->ts_stage_entry = 0;
@@ -1164,7 +1145,8 @@ static bool s_session_round_new(void *a_arg)
                     a_session->chain->net_name, a_session->chain->name,
                         a_session->cur_round.id, l_sync_send_delay);
         if (l_sync_send_delay)
-            a_session->sync_timer = dap_timerfd_start(l_sync_send_delay * 1000, s_session_send_startsync_on_timer, a_session);
+            dap_proc_thread_timer_add_pri(a_session->proc_thread, s_session_send_startsync, a_session,
+                                          l_sync_send_delay * 1000, true, DAP_QUEUE_MSG_PRIORITY_NORMAL);
         else
             s_session_send_startsync(a_session);
     }
@@ -1476,8 +1458,6 @@ static void s_session_proc_state(void *a_arg)
     dap_chain_esbocs_session_t *l_session = a_arg;
     if (!l_session->cs_timer)
         return; // Timer is inactive
-    //if (pthread_mutex_trylock(&l_session->mutex) != 0)
-    //    return; // Session is busy
     bool l_cs_debug = PVT(l_session->esbocs)->debug;
     dap_time_t l_time = dap_time_now();
     switch (l_session->state) {
@@ -1582,8 +1562,6 @@ static void s_session_proc_state(void *a_arg)
     default:
         break;
     }
-
-    //pthread_mutex_unlock(&l_session->mutex);
 }
 
 static void s_message_chain_add(dap_chain_esbocs_session_t *a_session,
@@ -2219,10 +2197,8 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain
     dap_hash_fast(l_message, a_data_size, &l_data_hash);
 
     if (a_sender_node_addr) { //Process network messages only
-        //pthread_mutex_lock(&l_session->mutex);
         if (l_message->hdr.chain_id.uint64 != l_session->chain->id.uint64) {
             debug_if(l_cs_debug, L_MSG, "Invalid chain ID %"DAP_UINT64_FORMAT_U, l_message->hdr.chain_id.uint64);
-            //goto session_unlock;
             return;
         }
         // check hash message dup
@@ -2233,7 +2209,6 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain
                                         " Message rejected: message hash is exists in chain (duplicate)",
                                             l_session->chain->net_name, l_session->chain->name,
                                                 l_session->cur_round.id, l_message->hdr.attempt_num);
-            //goto session_unlock;
             return;
         }
         l_message->hdr.sign_size = 0;   // restore header on signing time
@@ -2242,7 +2217,6 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain
                                         " Message rejected from addr:"NODE_ADDR_FP_STR" not passed verification",
                                             l_session->chain->net_name, l_session->chain->name, l_session->cur_round.id,
                                                 l_session->cur_round.attempt_num, NODE_ADDR_FP_ARGS(a_sender_node_addr));
-            //goto session_unlock;
             return;
         }
         l_message->hdr.sign_size = l_sign_size; // restore original header
@@ -2255,7 +2229,6 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain
                                                 l_session->chain->net_name, l_session->chain->name,
                                                     l_session->cur_round.id);
                 s_session_sync_queue_add(l_session, l_message, a_data_size);
-                //goto session_unlock;
                 return;
             }
         } else if (l_message->hdr.round_id != l_session->cur_round.id) {
@@ -2291,7 +2264,6 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain
                                                     l_session->chain->net_name, l_session->chain->name,
                                                         l_session->cur_round.id, l_message->hdr.attempt_num,
                                                             s_voting_msg_type_to_str(l_message->hdr.type));
-                    //goto session_unlock;
                     return;
                 }
             }
@@ -2328,7 +2300,6 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain
                                     " Message rejected: validator key:%s not in the current validators list or not synced yet",
                                         l_session->chain->net_name, l_session->chain->name, l_session->cur_round.id,
                                             l_message->hdr.attempt_num, l_validator_addr_str);
-        //goto session_unlock;
         return;
     }
 
@@ -2468,7 +2439,6 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain
         l_store = DAP_NEW_Z(dap_chain_esbocs_store_t);
         if (!l_store) {
             log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-            //goto session_unlock;
             return;
         }
         l_store->candidate_size = l_candidate_size;
@@ -2695,9 +2665,6 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain
     default:
         break;
     }
-//session_unlock:
-    //if (a_sender_node_addr) //Process network message
-    //    pthread_mutex_unlock(&l_session->mutex);
 }
 
 static void s_message_send(dap_chain_esbocs_session_t *a_session, uint8_t a_message_type, dap_hash_fast_t *a_block_hash,
@@ -2743,7 +2710,7 @@ static void s_message_send(dap_chain_esbocs_session_t *a_session, uint8_t a_mess
                                                a_message_type, l_message, l_message_size + l_sign_size);
                 continue;
             }
-            /*struct esbocs_msg_args *l_args = DAP_NEW_SIZE(struct esbocs_msg_args,
+            struct esbocs_msg_args *l_args = DAP_NEW_SIZE(struct esbocs_msg_args,
                                                           sizeof(struct esbocs_msg_args) + l_message_size + l_sign_size);
             if (!l_args) {
                 log_it(L_CRITICAL, "%s", c_error_memory_alloc);
@@ -2754,8 +2721,7 @@ static void s_message_send(dap_chain_esbocs_session_t *a_session, uint8_t a_mess
             l_args->session = a_session;
             l_args->message_size = l_message_size + l_sign_size;
             memcpy(l_args->message, l_message, l_message_size + l_sign_size);
-            dap_proc_thread_callback_add(a_session->proc_thread, s_process_incoming_message, l_args);*/
-            s_session_packet_in(a_session, &a_session->my_addr, (byte_t*)l_message, l_message_size + l_sign_size);
+            dap_proc_thread_callback_add(a_session->proc_thread, s_process_incoming_message, l_args);
         }
     }
     DAP_DELETE(l_message);
@@ -3108,7 +3074,7 @@ static int s_cli_esbocs(int a_argc, char **a_argv, void **a_str_reply)
                 dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_ESBOCS_PARAM_ERR,"Command '%s' requires parameter -val_count", l_subcmd_strs[l_subcmd]);
                 return -DAP_CHAIN_NODE_CLI_COM_ESBOCS_PARAM_ERR;
             }
-            uint256_t l_value = dap_chain_balance_scan(l_value_str);
+            uint256_t l_value = dap_uint256_scan_uninteger(l_value_str);
             if (IS_ZERO_256(l_value)) {
                 dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_ESBOCS_UNREC_COM_ERR,"Unrecognized number in '-val_count' param");
                 return -DAP_CHAIN_NODE_CLI_COM_ESBOCS_UNREC_COM_ERR;
diff --git a/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h b/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h
index e26355cf476bd50dc4a8496d4829c7c0ceedd057..e097d109a6114acb9a7e01ea5c6dc99e3323d675 100644
--- a/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h
+++ b/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h
@@ -201,7 +201,6 @@ typedef struct dap_chain_esbocs_session {
     dap_time_t ts_stage_entry; // time of current stage entrance
 
     dap_chain_esbocs_sync_item_t *sync_items;
-    dap_timerfd_t *sync_timer;
 
     dap_chain_addr_t my_signing_addr;
 
diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c
index 8fc3ad433d34ad4c9d290455a8c7292d15091d75..7ca0d0de3b5ed30b80e0ad7cca192fe492a0b965 100644
--- a/modules/mempool/dap_chain_mempool.c
+++ b/modules/mempool/dap_chain_mempool.c
@@ -1497,9 +1497,7 @@ void dap_chain_mempool_filter(dap_chain_t *a_chain, int *a_removed){
             continue;
         }
         //Filter hash
-        char *l_hash_content_str;
-        dap_get_data_hash_str_static(l_datum->data, l_datum->header.data_size, l_hash_content_str);
-        if (dap_strcmp(l_hash_content_str, l_objs[i].key) != 0) {
+        if (dap_strcmp(dap_get_data_hash_str(l_datum->data, l_datum->header.data_size).s, l_objs[i].key) != 0) {
             l_removed++;
             log_it(L_NOTICE, "Removed datum from mempool with \"%s\" key group %s. The hash of the contents of the "
                              "datum does not match the key.", l_objs[i].key, l_gdb_group);
diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c
index b59f1894a4f24330f60e12903278a50c6bd339fd..f20e687aafcc675b94b2f1408712c1c887d8649e 100644
--- a/modules/net/dap_chain_ledger.c
+++ b/modules/net/dap_chain_ledger.c
@@ -64,7 +64,7 @@ typedef struct dap_ledger_verificator {
     int subtype;    // hash key
     dap_ledger_verificator_callback_t callback;
     dap_ledger_updater_callback_t callback_added;
-    dap_ledger_updater_callback_t callback_deleted;
+    dap_ledger_delete_callback_t callback_deleted;
     UT_hash_handle hh;
 } dap_ledger_verificator_t;
 
@@ -276,8 +276,8 @@ typedef struct dap_ledger_private {
     dap_list_t *bridged_tx_notifiers;
     dap_list_t *tx_add_notifiers;
     dap_ledger_cache_tx_check_callback_t cache_tx_check_callback;
-    // HAL
-    dap_ledger_hal_item_t *hal_items;
+    // White- and blacklist
+    dap_ledger_hal_item_t *hal_items, *hrl_items;
 } dap_ledger_private_t;
 
 #define PVT(a) ( (dap_ledger_private_t *) a->_internal )
@@ -561,6 +561,12 @@ inline static dap_ledger_hal_item_t *s_check_hal(dap_ledger_t *a_ledger, dap_has
     return ret;
 }
 
+bool dap_ledger_datum_is_blacklisted(dap_ledger_t *a_ledger, dap_hash_fast_t a_hash) {
+    dap_ledger_hal_item_t *ret = NULL;
+    HASH_FIND(hh, PVT(a_ledger)->hrl_items, &a_hash, sizeof(dap_hash_fast_t), ret);
+    return debug_if(s_debug_more && ret, L_MSG, "Datum %s is blacklisted", dap_hash_fast_to_str_static(&a_hash)), !!ret;
+}
+
 inline static dap_ledger_token_item_t *s_ledger_find_token(dap_ledger_t *a_ledger, const char *a_token_ticker)
 {
     dap_return_val_if_fail(a_ledger && a_token_ticker, NULL);
@@ -2557,27 +2563,24 @@ dap_ledger_t *dap_ledger_create(dap_chain_net_t *a_net, uint16_t a_flags)
         if (strlen(l_entry_name) > 4) {
             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);
+                log_it(L_DEBUG,"Open chain config \"%s.%s\"...", a_net->pub.name, l_entry_name);
                 l_chains_path = dap_strdup_printf("network/%s/%s", a_net->pub.name, l_entry_name);
                 dap_config_t * l_cfg = dap_config_open(l_chains_path);
-                uint16_t l_whitelist_size;
-                const char **l_whitelist = dap_config_get_array_str(l_cfg, "ledger", "hard_accept_list", &l_whitelist_size);
-                for (uint16_t i = 0; i < l_whitelist_size; ++i) {
-                    dap_ledger_hal_item_t *l_hal_item = DAP_NEW_Z(dap_ledger_hal_item_t);
-                    if (!l_hal_item) {
-                        log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                        DAP_DEL_Z(l_ledger_pvt);
-                        DAP_DEL_Z(l_ledger);
-                        dap_config_close(l_cfg);
-                        DAP_DELETE (l_entry_name);
-                        closedir(l_chains_dir);
-                        return NULL;
-                    }
-                    dap_chain_hash_fast_from_str(l_whitelist[i], &l_hal_item->hash);
-                    HASH_ADD(hh, l_ledger_pvt->hal_items, hash, sizeof(l_hal_item->hash), l_hal_item);
+                uint16_t l_whitelist_size, l_blacklist_size, i;
+                const char **l_whitelist = dap_config_get_array_str(l_cfg, "ledger", "hard_accept_list", &l_whitelist_size),
+                           **l_blacklist = dap_config_get_array_str(l_cfg, "ledger", "hard_reject_list", &l_blacklist_size);
+                for (i = 0; i < l_blacklist_size; ++i) {
+                    dap_ledger_hal_item_t *l_item = DAP_NEW_Z(dap_ledger_hal_item_t);
+                    dap_chain_hash_fast_from_str(l_blacklist[i], &l_item->hash);
+                    HASH_ADD(hh, l_ledger_pvt->hrl_items, hash, sizeof(dap_hash_fast_t), l_item);
+                }
+                for (i = 0; i < l_whitelist_size; ++i) {
+                    dap_ledger_hal_item_t *l_item = DAP_NEW_Z(dap_ledger_hal_item_t);
+                    dap_chain_hash_fast_from_str(l_whitelist[i], &l_item->hash);
+                    HASH_ADD(hh, l_ledger_pvt->hal_items, hash, sizeof(dap_hash_fast_t), l_item);
                 }
                 dap_config_close(l_cfg);
-                log_it(L_DEBUG, "HAL items count for chain %s : %d", l_entry_name, l_whitelist_size);
+                log_it(L_DEBUG, "Chain %s.%s has %d datums in HAL and %d datums in HRL", a_net->pub.name, l_entry_name, l_whitelist_size, l_blacklist_size);
             }
         }
         DAP_DELETE (l_entry_name);
@@ -4444,7 +4447,7 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha
             HASH_FIND_INT(s_verificators, &l_tmp, l_verificator);
             pthread_rwlock_unlock(&s_verificators_rwlock);
             if (l_verificator && l_verificator->callback_added)
-                l_verificator->callback_added(a_ledger, a_tx, l_bound_item->cond);
+                l_verificator->callback_added(a_ledger, a_tx, a_tx_hash, l_bound_item->cond);
         } break;
 
         default:
@@ -4497,7 +4500,7 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha
             HASH_FIND_INT(s_verificators, &l_tmp, l_verificator);
             pthread_rwlock_unlock(&s_verificators_rwlock);
             if (l_verificator && l_verificator->callback_added)
-                l_verificator->callback_added(a_ledger, a_tx, NULL);
+                l_verificator->callback_added(a_ledger, a_tx, a_tx_hash, NULL);
             continue;   // balance raise will be with next conditional transaction
         }
 
@@ -4650,7 +4653,7 @@ FIN:
     return l_ret;
 }
 
-void dap_leger_load_end(dap_ledger_t *a_ledger)
+void dap_ledger_load_end(dap_ledger_t *a_ledger)
 {
     pthread_rwlock_wrlock(&PVT(a_ledger)->ledger_rwlock);
     HASH_SORT(PVT(a_ledger)->ledger_items, s_sort_ledger_tx_item);
@@ -5610,7 +5613,7 @@ dap_list_t *dap_ledger_get_list_tx_outs(dap_ledger_t *a_ledger, const char *a_to
 
 
 // Add new verificator callback with associated subtype. Returns 1 if callback replaced, -1 error, overwise returns 0
-int dap_ledger_verificator_add(dap_chain_tx_out_cond_subtype_t a_subtype, dap_ledger_verificator_callback_t a_callback, dap_ledger_updater_callback_t a_callback_added, dap_ledger_updater_callback_t a_callback_deleted)
+int dap_ledger_verificator_add(dap_chain_tx_out_cond_subtype_t a_subtype, dap_ledger_verificator_callback_t a_callback, dap_ledger_updater_callback_t a_callback_added, dap_ledger_delete_callback_t a_callback_deleted)
 {
     dap_ledger_verificator_t *l_new_verificator = NULL;
     int l_tmp = (int)a_subtype;
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index 9fd5effec1b3d730b82298d46d5a686196bdeb97..d411a57f2a05536e9228982b9f282931849fd390 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -495,11 +495,15 @@ int s_link_manager_link_request(uint64_t a_net_id)
     if (l_net_pvt->state == NET_STATE_LINKS_PREPARE)
         l_net_pvt->state = NET_STATE_LINKS_CONNECTING;
     struct request_link_info *l_balancer_link = s_balancer_link_from_cfg(l_net);
-    if (!l_balancer_link) {
-        log_it(L_ERROR, "Can't process balancer link %s request in nte %s", dap_chain_net_balancer_type_to_str(PVT(l_net)->balancer_type), l_net->pub.name);
-        return -5;
-    }
-    return dap_chain_net_balancer_request(l_net, l_balancer_link->addr,  l_balancer_link->port, PVT(l_net)->balancer_type);
+    if (!l_balancer_link)
+        return log_it(L_ERROR, "Can't process balancer link %s request in net %s", 
+                        dap_chain_net_balancer_type_to_str(PVT(l_net)->balancer_type), l_net->pub.name), -5;
+    dap_balancer_link_request_t *l_arg = DAP_NEW_Z(dap_balancer_link_request_t);
+    l_arg->net = l_net;
+    l_arg->host_addr = (const char*)l_balancer_link->addr;
+    l_arg->host_port = l_balancer_link->port;
+    l_arg->type = PVT(l_net)->balancer_type;
+    return dap_worker_exec_callback_on(dap_worker_get_auto(), dap_chain_net_balancer_request, l_arg), 0;
 }
 
 int s_link_manager_fill_net_info(dap_link_t *a_link)
@@ -2031,9 +2035,8 @@ int s_net_init(const char *a_net_name, uint16_t a_acl_idx)
         }
         if (!l_chain->callback_get_poa_certs)
             continue;
-        l_net->pub.keys = l_chain->callback_get_poa_certs(l_chain, NULL, NULL);
-        if (l_net->pub.keys)
-            break;
+        if (!l_net->pub.keys)
+            l_net->pub.keys = l_chain->callback_get_poa_certs(l_chain, NULL, NULL);
     }
     if (!l_net->pub.keys)
         log_it(L_WARNING, "PoA certificates for net %s not found", l_net->pub.name);
@@ -2111,7 +2114,7 @@ bool s_net_load(void *a_arg)
         l_chain = l_chain->next;
     }
     l_net_pvt->load_mode = false;
-    dap_leger_load_end(l_net->pub.ledger);
+    dap_ledger_load_end(l_net->pub.ledger);
 
     // Do specific role actions post-chain created
     l_net_pvt->state_target = NET_STATE_OFFLINE;
@@ -2807,6 +2810,8 @@ int dap_chain_datum_add(dap_chain_t *a_chain, dap_chain_datum_t *a_datum, size_t
         return -101;
     }
     dap_ledger_t *l_ledger = dap_chain_net_by_id(a_chain->net_id)->pub.ledger;
+    if ( dap_ledger_datum_is_blacklisted(l_ledger, *a_datum_hash) )
+        return log_it(L_ERROR, "Datum is blackilsted"), -100;
     switch (a_datum->header.type_id) {
         case DAP_CHAIN_DATUM_DECREE: {
             dap_chain_datum_decree_t *l_decree = (dap_chain_datum_decree_t *)a_datum->data;
@@ -3209,10 +3214,10 @@ static dap_chain_t *s_switch_sync_chain(dap_chain_net_t *a_net)
     }
     l_net_pvt->sync_context.cur_chain = l_curr_chain;
     if (l_curr_chain) {
-        log_it(L_DEBUG, "Go to chain \"%s\" for net %s", l_curr_chain->name, l_curr_chain->net_name);
+        debug_if(s_debug_more, L_DEBUG, "Go to chain \"%s\" for net %s", l_curr_chain->name, l_curr_chain->net_name);
         return l_curr_chain;
     }
-    log_it(L_DEBUG, "Go to next chain: <NULL>");
+    debug_if(s_debug_more, L_DEBUG, "Go to next chain: <NULL>");
     if (l_net_pvt->state_target != NET_STATE_ONLINE) {
         dap_chain_net_state_go_to(a_net, NET_STATE_OFFLINE);
         return NULL;
@@ -3221,7 +3226,7 @@ static dap_chain_t *s_switch_sync_chain(dap_chain_net_t *a_net)
     l_net_pvt->state = NET_STATE_ONLINE;
     s_net_states_proc(a_net);
     if(l_prev_state == NET_STATE_SYNC_CHAINS)
-        dap_leger_load_end(a_net->pub.ledger);
+        dap_ledger_load_end(a_net->pub.ledger);
     return NULL;
 }
 
@@ -3315,7 +3320,7 @@ static bool s_net_states_proc(void *a_arg)
     assert(l_net_pvt);
     if (l_net_pvt->state_target == NET_STATE_OFFLINE) {
         if(l_net_pvt->state == NET_STATE_SYNC_CHAINS)
-            dap_leger_load_end(l_net->pub.ledger);
+            dap_ledger_load_end(l_net->pub.ledger);
         l_net_pvt->state = NET_STATE_OFFLINE;
     }
 
@@ -3401,4 +3406,4 @@ DAP_INLINE dap_chain_net_state_t dap_chain_net_get_target_state(dap_chain_net_t
     return PVT(a_net)->state_target;
 }
 
-/*------------------------------------State machine block end---------------------------------*/
\ No newline at end of file
+/*------------------------------------State machine block end---------------------------------*/
diff --git a/modules/net/dap_chain_net_anchor.c b/modules/net/dap_chain_net_anchor.c
index 5b710283932c645bf0fef6bd8888d2943798753c..84984130f327ab2764950032315e9062643e77d2 100644
--- a/modules/net/dap_chain_net_anchor.c
+++ b/modules/net/dap_chain_net_anchor.c
@@ -168,7 +168,7 @@ int dap_chain_net_anchor_load(dap_chain_datum_anchor_t * a_anchor, dap_chain_t *
         return -109;
     }
 
-    if ((ret_val = dap_chain_net_decree_apply(&l_hash, NULL, a_chain)) != 0){
+    if ((ret_val = dap_chain_net_decree_apply(&l_hash, NULL, a_chain, true)) != 0){
         debug_if(s_debug_more, L_WARNING, "Decree applying failed");
         return ret_val;
     }
@@ -315,7 +315,7 @@ int dap_chain_net_anchor_unload(dap_chain_datum_anchor_t * a_anchor, dap_chain_t
                         return -109;
                     }
 
-                    if((ret_val = dap_chain_net_decree_apply(&l_hash, NULL, a_chain))!=0){
+                    if((ret_val = dap_chain_net_decree_apply(&l_hash, NULL, a_chain, true))!=0){
                         log_it(L_WARNING,"Decree applying failed");
                         return ret_val;
                     }
@@ -351,7 +351,7 @@ int dap_chain_net_anchor_unload(dap_chain_datum_anchor_t * a_anchor, dap_chain_t
                         log_it(L_WARNING,"Can not find datum hash in anchor data");
                         return -109;
                     }
-                    if((ret_val = dap_chain_net_decree_apply(&l_hash, NULL, a_chain))!=0){
+                    if((ret_val = dap_chain_net_decree_apply(&l_hash, NULL, a_chain, true))!=0){
                         log_it(L_WARNING,"Decree applying failed");
                         return ret_val;
                     }
@@ -368,7 +368,7 @@ int dap_chain_net_anchor_unload(dap_chain_datum_anchor_t * a_anchor, dap_chain_t
                         log_it(L_WARNING,"Can not find datum hash in anchor data");
                         return -109;
                     }
-                    if((ret_val = dap_chain_net_decree_apply(&l_hash, NULL, a_chain))!=0){
+                    if((ret_val = dap_chain_net_decree_apply(&l_hash, NULL, a_chain, true))!=0){
                         log_it(L_WARNING,"Decree applying failed");
                         return ret_val;
                     }
@@ -389,7 +389,7 @@ int dap_chain_net_anchor_unload(dap_chain_datum_anchor_t * a_anchor, dap_chain_t
                         return -109;
                     }
 
-                    if((ret_val = dap_chain_net_decree_apply(&l_hash, NULL, a_chain))!=0){
+                    if((ret_val = dap_chain_net_decree_apply(&l_hash, NULL, a_chain, true))!=0){
                         log_it(L_WARNING,"Decree applying failed");
                         return ret_val;
                     }
diff --git a/modules/net/dap_chain_net_balancer.c b/modules/net/dap_chain_net_balancer.c
index 1460bce84e96d0110971b376ba051e6a47e98653..bbd3dd7320599a509763cbe6ca94d132215b9c75 100644
--- a/modules/net/dap_chain_net_balancer.c
+++ b/modules/net/dap_chain_net_balancer.c
@@ -44,15 +44,6 @@ typedef struct dap_balancer_request_info {
     UT_hash_handle hh;
 } dap_balancer_request_info_t;
 
-typedef struct dap_balancer_link_request {
-    const char* host_addr;
-    uint16_t host_port;
-    dap_chain_net_t *net;
-    dap_worker_t *worker;
-    uint16_t required_links_count;
-    dap_balancer_request_info_t *request_info;
-} dap_balancer_link_request_t;
-
 static_assert(sizeof(dap_chain_net_links_t) + sizeof(dap_chain_node_info_old_t) < DAP_BALANCER_MAX_REPLY_SIZE, "DAP_BALANCER_MAX_REPLY_SIZE cannot accommodate information minimum about 1 link");
 static const size_t s_max_links_response_count = (DAP_BALANCER_MAX_REPLY_SIZE - sizeof(dap_chain_net_links_t)) / sizeof(dap_chain_node_info_old_t);
 static const dap_time_t s_request_period = 5; // sec
@@ -465,66 +456,53 @@ dap_link_info_t *dap_chain_net_balancer_dns_issue_link(const char *a_net_name)
  * @param a_balancer_type - http or DNS
  * @return if ok 0, error - other
  */
-int dap_chain_net_balancer_request(dap_chain_net_t *a_net, const char *a_host_addr, uint16_t a_host_port, int a_balancer_type)
+void dap_chain_net_balancer_request(void *a_arg)
 {
 // sanity check
-    dap_return_val_if_pass(!a_net, -1);
+    dap_return_if_fail(a_arg);
+    dap_balancer_link_request_t *l_arg = (dap_balancer_link_request_t*)a_arg;
 // period request check
     dap_balancer_request_info_t *l_item = NULL;
-    HASH_FIND(hh, s_request_info_items, &a_net->pub.id, sizeof(a_net->pub.id), l_item);
+    HASH_FIND(hh, s_request_info_items, &l_arg->net->pub.id, sizeof(l_arg->net->pub.id), l_item);
     if (!l_item) {
-        DAP_NEW_Z_RET_VAL(l_item, dap_balancer_request_info_t, -2, NULL);
-        l_item->net_id = a_net->pub.id;
+        DAP_NEW_Z_RET(l_item, dap_balancer_request_info_t, NULL);
+        l_item->net_id = l_arg->net->pub.id;
         HASH_ADD(hh, s_request_info_items, net_id, sizeof(l_item->net_id), l_item);
     }
-    if (l_item->request_time + DAP_CHAIN_NET_BALANCER_REQUEST_DELAY > dap_time_now()) {
-        log_it(L_DEBUG, "Who understands life, he is in no hurry. Dear %s, please wait few seconds", a_net->pub.name);
-        return 0;
-    }
+    if (l_item->request_time + DAP_CHAIN_NET_BALANCER_REQUEST_DELAY > dap_time_now())
+        return log_it(L_DEBUG, "Who understands life, he is in no hurry. Dear %s, please wait few seconds", l_arg->net->pub.name);
 // preparing to request
     size_t
         l_ignored_addrs_size = 0,
-        l_required_links_count = dap_link_manager_needed_links_count(a_net->pub.id.uint64);
+        l_required_links_count = dap_link_manager_needed_links_count(l_arg->net->pub.id.uint64);
     dap_chain_net_links_t
-        *l_ignored_addrs = s_get_ignored_node_addrs(a_net, &l_ignored_addrs_size),
-        *l_links = s_get_node_addrs(a_net, l_required_links_count, l_ignored_addrs, false);
+        *l_ignored_addrs = s_get_ignored_node_addrs(l_arg->net, &l_ignored_addrs_size),
+        *l_links = s_get_node_addrs(l_arg->net, l_required_links_count, l_ignored_addrs, false);
 // links from local GDB
     if (l_links) {
-        log_it(L_INFO, "%"DAP_UINT64_FORMAT_U" links successful prepared from global-db in net %s", l_links->count_node, a_net->pub.name);
-        s_balancer_link_prepare_success(a_net, l_links, NULL, 0);
-        if (l_links->count_node >= l_required_links_count) {
-            DAP_DEL_MULTY(l_ignored_addrs, l_links);
-            return 0;
-        }
+        log_it(L_INFO, "%"DAP_UINT64_FORMAT_U" links successful prepared from global-db in net %s", l_links->count_node, l_arg->net->pub.name);
+        s_balancer_link_prepare_success(l_arg->net, l_links, NULL, 0);
+        if (l_links->count_node >= l_required_links_count)
+            return DAP_DEL_MULTY(l_ignored_addrs, l_links);
         l_required_links_count -= l_links->count_node;
         DAP_DELETE(l_links);
     }
 // links from http balancer request
-    if (!a_host_addr || !a_host_port) {
-        log_it(L_INFO, "Can't read seed nodes addresses in net %s, work with local balancer only", a_net->pub.name);
-        DAP_DEL_Z(l_ignored_addrs);
-        return 0;
-    }
-    dap_balancer_link_request_t *l_balancer_request = NULL;
-    DAP_NEW_Z_RET_VAL(l_balancer_request, dap_balancer_link_request_t, -4, NULL);
-    *l_balancer_request = (dap_balancer_link_request_t) {
-        .host_addr = a_host_addr,
-        .host_port = a_host_port,
-        .net = a_net,
-        .worker = dap_worker_get_current(),
-        .required_links_count = l_required_links_count,
-        .request_info = l_item
-    };
+    if (!l_arg->host_addr || !*l_arg->host_addr || !l_arg->host_port)
+        return DAP_DELETE(l_ignored_addrs), log_it(L_INFO, "Can't read seed nodes addresses in net %s, work with local balancer only",
+                                                            l_arg->net->pub.name);
+    l_arg->worker = dap_worker_get_current();
+    l_arg->required_links_count = l_required_links_count;
+    l_arg->request_info = l_item;
     log_it(L_DEBUG, "Start balancer %s request to %s:%u in net %s",
-           dap_chain_net_balancer_type_to_str(a_balancer_type), l_balancer_request->host_addr, l_balancer_request->host_port, a_net->pub.name);
+                    dap_chain_net_balancer_type_to_str(l_arg->type), l_arg->host_addr, l_arg->host_port, l_arg->net->pub.name);
     
-    int ret;
-    if (a_balancer_type == DAP_CHAIN_NET_BALANCER_TYPE_HTTP) {
+    if (l_arg->type == DAP_CHAIN_NET_BALANCER_TYPE_HTTP) {
         char *l_ignored_addrs_str = NULL;
         if (l_ignored_addrs) {
-            DAP_NEW_Z_SIZE_RET_VAL(
+            DAP_NEW_Z_SIZE_RET(
                 l_ignored_addrs_str, char, DAP_ENC_BASE64_ENCODE_SIZE(l_ignored_addrs_size) + 1,
-                -7, l_ignored_addrs, l_balancer_request);
+                l_ignored_addrs, l_arg);
             dap_enc_base64_encode(l_ignored_addrs, l_ignored_addrs_size, l_ignored_addrs_str, DAP_ENC_DATA_TYPE_B64);
             DAP_DELETE(l_ignored_addrs);
         }
@@ -534,38 +512,28 @@ int dap_chain_net_balancer_request(dap_chain_net_t *a_net, const char *a_host_ad
                                                 DAP_BALANCER_URI_HASH,
                                                 DAP_BALANCER_PROTOCOL_VERSION,
                                                 (int)l_required_links_count,
-                                                a_net->pub.name,
+                                                l_arg->net->pub.name,
                                                 l_ignored_addrs_str ? l_ignored_addrs_str : "");
-        ret = dap_client_http_request(l_balancer_request->worker,
-                                                l_balancer_request->host_addr,
-                                                l_balancer_request->host_port,
-                                                "GET",
-                                                "text/text",
-                                                l_request,
-                                                NULL,
-                                                0,
-                                                NULL,
-                                                s_http_balancer_link_prepare_success,
-                                                s_http_balancer_link_prepare_error,
-                                                l_balancer_request,
-                                                NULL) == NULL;
+        if (! dap_client_http_request(l_arg->worker, l_arg->host_addr, l_arg->host_port,
+                                       "GET", "text/text", l_request, NULL, 0, NULL,
+                                       s_http_balancer_link_prepare_success, s_http_balancer_link_prepare_error,
+                                       l_arg, NULL) )
+        {
+            log_it(L_ERROR, "Can't process balancer link %s request in net %s",
+                            dap_chain_net_balancer_type_to_str(l_arg->type), l_arg->net->pub.name);
+        }
         DAP_DEL_MULTY(l_ignored_addrs_str, l_request);
     } else {
-        l_balancer_request->host_port = DNS_LISTEN_PORT;
+        l_arg->host_port = DNS_LISTEN_PORT;
         // TODO: change signature and implementation
-        ret = /* dap_chain_node_info_dns_request(l_balancer_request->worker,
-                                                l_link_node_info->hdr.ext_addr_v4,
-                                                l_link_node_info->hdr.ext_port,
-                                                a_net->pub.name,
-                                                s_dns_balancer_link_prepare_success,
-                                                s_dns_balancer_link_prepare_error,
-                                                l_balancer_request); */ -1;
-    }
-    if (ret) {
-        log_it(L_ERROR, "Can't process balancer link %s request in net %s", dap_chain_net_balancer_type_to_str(a_balancer_type), a_net->pub.name);
-        return -6;
+        /* dap_chain_node_info_dns_request(l_balancer_request->worker,
+                                            l_link_node_info->hdr.ext_addr_v4,
+                                            l_link_node_info->hdr.ext_port,
+                                            a_net->pub.name,
+                                            s_dns_balancer_link_prepare_success,
+                                            s_dns_balancer_link_prepare_error,
+                                            l_balancer_request); */
     }
-    return 0;
 }
 
 /**
diff --git a/modules/net/dap_chain_net_decree.c b/modules/net/dap_chain_net_decree.c
index 6aafb2826aa07cfe23cf92ab5e583c71c95ed2af..28fbef933c7df9828f47ba14f32b60fbf6cf9a01 100644
--- a/modules/net/dap_chain_net_decree.c
+++ b/modules/net/dap_chain_net_decree.c
@@ -52,7 +52,7 @@ typedef struct decree_table {
 
 // Private fuctions prototype
 static bool s_verify_pkey (dap_sign_t *a_sign, dap_chain_net_t *a_net);
-static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain_net_t *a_net, bool a_apply, bool a_load_mode);
+static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain_net_t *a_net, bool a_apply, bool a_anchored);
 static int s_service_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain_net_t *a_net, bool a_apply);
 
 static bool s_debug_more = false;
@@ -119,7 +119,7 @@ void dap_chain_net_decree_purge(dap_chain_net_t *a_net)
     dap_chain_net_decree_init(a_net);
 }
 
-static int s_decree_verify(dap_chain_net_t *a_net, dap_chain_datum_decree_t *a_decree, size_t a_data_size, dap_chain_hash_fast_t *a_decree_hash, bool a_load_mode)
+static int s_decree_verify(dap_chain_net_t *a_net, dap_chain_datum_decree_t *a_decree, size_t a_data_size, dap_chain_hash_fast_t *a_decree_hash, bool a_anchored)
 {
     if (a_data_size < sizeof(dap_chain_datum_decree_t)) {
         log_it(L_WARNING, "Decree size is too small");
@@ -205,7 +205,7 @@ static int s_decree_verify(dap_chain_net_t *a_net, dap_chain_datum_decree_t *a_d
     int l_ret = 0;
     switch(a_decree->header.type) {
     case DAP_CHAIN_DATUM_DECREE_TYPE_COMMON:
-        l_ret = s_common_decree_handler(a_decree, a_net, false, a_load_mode);
+        l_ret = s_common_decree_handler(a_decree, a_net, false, a_anchored);
         break;
     case DAP_CHAIN_DATUM_DECREE_TYPE_SERVICE:
         l_ret = s_service_decree_handler(a_decree, a_net, false);
@@ -227,7 +227,7 @@ int dap_chain_net_decree_verify(dap_chain_net_t *a_net, dap_chain_datum_decree_t
     return s_decree_verify(a_net, a_decree, a_data_size, a_decree_hash, false);
 }
 
-int dap_chain_net_decree_apply(dap_hash_fast_t *a_decree_hash, dap_chain_datum_decree_t *a_decree, dap_chain_t *a_chain)
+int dap_chain_net_decree_apply(dap_hash_fast_t *a_decree_hash, dap_chain_datum_decree_t *a_decree, dap_chain_t *a_chain, bool a_anchored)
 {
     int ret_val = 0;
     dap_chain_net_t *l_net = NULL;
@@ -282,7 +282,7 @@ int dap_chain_net_decree_apply(dap_hash_fast_t *a_decree_hash, dap_chain_datum_d
     // Process decree
     switch(l_new_decree->decree->header.type) {
     case DAP_CHAIN_DATUM_DECREE_TYPE_COMMON:
-        ret_val = s_common_decree_handler(l_new_decree->decree, l_net, true, false);
+        ret_val = s_common_decree_handler(l_new_decree->decree, l_net, true, a_anchored);
         break;
     case DAP_CHAIN_DATUM_DECREE_TYPE_SERVICE:
         ret_val = s_service_decree_handler(l_new_decree->decree, l_net, true);
@@ -318,12 +318,12 @@ int dap_chain_net_decree_load(dap_chain_datum_decree_t * a_decree, dap_chain_t *
 
     size_t l_data_size = dap_chain_datum_decree_get_size(a_decree);
 
-    if ((ret_val = s_decree_verify(l_net, a_decree, l_data_size, a_decree_hash, true)) != 0) {
+    if ((ret_val = s_decree_verify(l_net, a_decree, l_data_size, a_decree_hash, false)) != 0) {
         //log_it(L_ERROR, "Decree verification failed!");
         return ret_val;
     }
 
-    return dap_chain_net_decree_apply(a_decree_hash, a_decree, a_chain);
+    return dap_chain_net_decree_apply(a_decree_hash, a_decree, a_chain, false);
 }
 
 int dap_chain_net_decree_reset_applied(dap_chain_net_t *a_net, dap_chain_hash_fast_t *a_decree_hash)
@@ -356,7 +356,7 @@ static bool s_verify_pkey (dap_sign_t *a_sign, dap_chain_net_t *a_net)
     return false;
 }
 
-static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain_net_t *a_net, bool a_apply, bool a_load_mode)
+static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain_net_t *a_net, bool a_apply, bool a_anchored)
 {
     uint256_t l_value;
     uint32_t l_sign_type;
@@ -433,10 +433,8 @@ static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain
                 log_it(L_WARNING,"Can't get signer node address from decree.");
                 return -108;
             }
-            if (a_load_mode) {
-                assert(!a_apply);
+            if (!a_anchored)
                 break;
-            }
             if (dap_chain_net_srv_stake_verify_key_and_node(&l_addr, &l_node_addr)) {
                 debug_if(s_debug_more, L_WARNING, "Key and node verification error");
                 return -109;
@@ -485,6 +483,8 @@ static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain
                 log_it(L_WARNING, "Can't apply this decree to specified chain");
                 return -115;
             }
+            if (!a_anchored)
+                break;
             uint16_t l_decree_count = (uint16_t)dap_chain_uint256_to(l_value);
             uint16_t l_current_count = dap_chain_net_srv_stake_get_total_keys(a_net->pub.id, NULL);
             if (l_decree_count > l_current_count) {
diff --git a/modules/net/dap_chain_net_node_list.c b/modules/net/dap_chain_net_node_list.c
index 52119f83ee1dcbfbf77d5bbeab3e3543c96f8ac2..a4d6cb70db35f5732cd880609480a4fded514e3c 100644
--- a/modules/net/dap_chain_net_node_list.c
+++ b/modules/net/dap_chain_net_node_list.c
@@ -124,7 +124,7 @@ void dap_chain_net_node_check_http_issue_link(dap_http_simple_t *a_http_simple,
     uint8_t l_response = ERR_UNKNOWN;
     switch (l_issue_method) {
     case 'a': {
-        uint8_t l_host_size = dap_min(INET6_ADDRSTRLEN, (int)dap_strlen(a_http_simple->es_hostaddr) + 1);
+        uint8_t l_host_size = (uint8_t)dap_strlen(a_http_simple->es_hostaddr) + 1;
         l_node_info = DAP_NEW_STACK_SIZE(dap_chain_node_info_t, sizeof(dap_chain_node_info_t) + l_host_size);
         *l_node_info = (dap_chain_node_info_t) {
             .address.uint64 = addr,
@@ -133,8 +133,7 @@ void dap_chain_net_node_check_http_issue_link(dap_http_simple_t *a_http_simple,
         };
         l_response = !dap_chain_net_balancer_handshake(l_node_info, l_net)
             ? s_dap_chain_net_node_list_add(l_net, l_node_info)
-            : ( log_it(L_DEBUG, "Can't do handshake with %s [ %s : %u ]", l_key, l_node_info->ext_host, l_node_info->ext_port),
-            ERR_HANDSHAKE );
+            : ( log_it(L_DEBUG, "Can't do handshake with %s [ %s : %u ]", l_key, l_node_info->ext_host, l_node_info->ext_port), ERR_HANDSHAKE );
         *l_return_code = Http_Status_OK;
     } break;
 
@@ -148,10 +147,8 @@ void dap_chain_net_node_check_http_issue_link(dap_http_simple_t *a_http_simple,
                 *l_return_code = Http_Status_Forbidden;
             } else {
                 l_response = !dap_global_db_del_sync(l_net->pub.gdb_nodes, l_key)
-                    ? ( log_it(L_DEBUG, "Node %s successfully deleted from nodelist", l_key),
-                    DELETED_OK )
-                    : ( log_it(L_DEBUG, "Can't delete node %s from nodelist", l_key),
-                    ERR_EXISTS );
+                    ? ( log_it(L_DEBUG, "Node %s successfully deleted from nodelist", l_key), DELETED_OK )
+                    : ( log_it(L_DEBUG, "Can't delete node %s from nodelist", l_key), ERR_EXISTS );
                 *l_return_code = Http_Status_OK;
             }
             DAP_DELETE(l_node_info);
@@ -159,11 +156,9 @@ void dap_chain_net_node_check_http_issue_link(dap_http_simple_t *a_http_simple,
     } break;
 
     default:
-        log_it(L_ERROR, "Unsupported protocol version/method in the request to dap_chain_net_node_list module");
-        *l_return_code = Http_Status_MethodNotAllowed;
-        return;
+        return *l_return_code = Http_Status_MethodNotAllowed, log_it(L_ERROR, "Unsupported protocol version/method");
     }
-    
+
     dap_http_simple_reply(a_http_simple, &l_response, sizeof(uint8_t));
 }
 
@@ -171,79 +166,110 @@ static void s_net_node_link_prepare_success(void *a_response, size_t a_response_
                                             http_status_code_t http_status_code) {
     (void)http_status_code;
     struct node_link_request *l_node_list_request = (struct node_link_request *)a_arg;
+#ifdef DAP_OS_WINDOWS
+    EnterCriticalSection(&l_node_list_request->wait_crit_sec);
+    l_node_list_request->response = *(uint8_t*)a_response;
+    WakeConditionVariable(&l_node_list_request->wait_cond);
+    LeaveCriticalSection(&l_node_list_request->wait_crit_sec);
+#else
     pthread_mutex_lock(&l_node_list_request->wait_mutex);
     l_node_list_request->response = *(uint8_t*)a_response;
     pthread_cond_signal(&l_node_list_request->wait_cond);
     pthread_mutex_unlock(&l_node_list_request->wait_mutex);
+#endif
 }
+
 static void s_net_node_link_prepare_error(int a_error_code, void *a_arg){
     struct node_link_request * l_node_list_request = (struct node_link_request *)a_arg;
     dap_chain_node_info_t *l_node_info = l_node_list_request->link_info;
-    if (!l_node_info) {
-        log_it(L_WARNING, "Link prepare error, code %d", a_error_code);
-        return;
-    }
+    if (!l_node_info)
+        return log_it(L_WARNING, "Link prepare error, code %d", a_error_code);
+#ifdef DAP_OS_WINDOWS
+    EnterCriticalSection(&l_node_list_request->wait_crit_sec);
+    l_node_list_request->response = a_error_code;
+    WakeConditionVariable(&l_node_list_request->wait_cond);
+    LeaveCriticalSection(&l_node_list_request->wait_crit_sec);
+#else
     pthread_mutex_lock(&l_node_list_request->wait_mutex);
     l_node_list_request->response = a_error_code;
     pthread_cond_signal(&l_node_list_request->wait_cond);
     pthread_mutex_unlock(&l_node_list_request->wait_mutex);
+#endif
     log_it(L_WARNING, "Link from  "NODE_ADDR_FP_STR" [ %s : %u ] prepare error with code %d",
            NODE_ADDR_FP_ARGS_S(l_node_info->address), l_node_info->ext_host,
            l_node_info->ext_port, a_error_code);
 }
-static struct node_link_request *s_node_list_request_init ()
+
+static struct node_link_request* s_node_list_request_init()
 {
     struct node_link_request *l_node_list_request = DAP_NEW_Z(struct node_link_request);
-    if(!l_node_list_request){
+    if (!l_node_list_request)
         return NULL;
-    }
-    l_node_list_request->worker = dap_events_worker_get_auto();
-    l_node_list_request->response = 0;
-
-    pthread_condattr_t attr;
-    pthread_condattr_init(&attr);
+#ifdef DAP_OS_WINDOWS
+    InitializeCriticalSection(&l_node_list_request->wait_crit_sec);
+    InitializeConditionVariable(&l_node_list_request->wait_cond);
+#else
+    pthread_mutex_init(&l_node_list_request->wait_mutex, NULL);
 #ifdef DAP_OS_DARWIN
-    struct timespec ts;
-    ts.tv_sec = 8;
-    ts.tv_nsec = 0;
-    pthread_cond_timedwait_relative_np(&l_node_list_request->wait_cond, &l_node_list_request->wait_mutex,
-                                       &ts);
+    pthread_cond_init(&l_node_list_request->wait_cond, NULL);
 #else
+    pthread_condattr_t attr;
+    pthread_condattr_init(&attr);
     pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
+    pthread_cond_init(&l_node_list_request->wait_cond, &attr);    
+#endif
 #endif
-    pthread_cond_init(&l_node_list_request->wait_cond, &attr);
-    pthread_mutex_init(&l_node_list_request->wait_mutex, NULL);
     return l_node_list_request;
 }
 
 static void s_node_list_request_deinit (struct node_link_request *a_node_list_request)
 {
+#ifdef DAP_OS_WINDOWS
+    DeleteCriticalSection(&a_node_list_request->wait_crit_sec);
+#else
     pthread_cond_destroy(&a_node_list_request->wait_cond);
     pthread_mutex_destroy(&a_node_list_request->wait_mutex);
+#endif
     DAP_DEL_Z(a_node_list_request->link_info);
 }
-static int dap_chain_net_node_list_wait(struct node_link_request *a_node_list_request, int a_timeout_ms){
+
+static int dap_chain_net_node_list_wait(struct node_link_request *a_node_list_request, int a_timeout_ms) {
+#ifdef DAP_OS_WINDOWS
+    EnterCriticalSection(&a_node_list_request->wait_crit_sec);
+    if (a_node_list_request->response)
+        return LeaveCriticalSection(&a_node_list_request->wait_crit_sec), a_node_list_request->response;
+    while (!a_node_list_request->response) {
+        if ( !SleepConditionVariableCS(&a_node_list_request->wait_cond, &a_node_list_request->wait_crit_sec, a_timeout_ms) )
+            a_node_list_request->response = GetLastError() == ERROR_TIMEOUT ? ERR_WAIT_TIMEOUT : ERR_UNKNOWN;
+    }
+    return LeaveCriticalSection(&a_node_list_request->wait_crit_sec), a_node_list_request->response;     
+#else
     pthread_mutex_lock(&a_node_list_request->wait_mutex);
     if(a_node_list_request->response)
-    {
-        pthread_mutex_unlock(&a_node_list_request->wait_mutex);
-        return a_node_list_request->response;
-    }
+        return pthread_mutex_unlock(&a_node_list_request->wait_mutex), a_node_list_request->response;
     struct timespec l_cond_timeout;
-    clock_gettime(CLOCK_REALTIME, &l_cond_timeout);
-    l_cond_timeout.tv_sec += a_timeout_ms/1000;
+#ifdef DAP_OS_DARWIN
+    l_cond_timeout = (struct timespec){ .tv_sec = a_timeout_ms / 1000 };
+#else
+    clock_gettime(CLOCK_MONOTONIC, &l_cond_timeout);
+    l_cond_timeout.tv_sec += a_timeout_ms / 1000;
+#endif
     while (!a_node_list_request->response) {
-        int l_wait = pthread_cond_timedwait(&a_node_list_request->wait_cond, &a_node_list_request->wait_mutex, &l_cond_timeout);
-        if (l_wait == ETIMEDOUT) {
-            log_it(L_NOTICE, "Waiting for status timeout");
+        switch (
+#ifdef DAP_OS_DARWIN
+            pthread_cond_timedwait_relative_np(&a_node_list_request->wait_cond, &a_node_list_request->wait_mutex, &l_cond_timeout)
+#else
+            pthread_cond_timedwait(&a_node_list_request->wait_cond, &a_node_list_request->wait_mutex, &l_cond_timeout)
+#endif
+        ) {
+        case ETIMEDOUT:
             a_node_list_request->response = ERR_WAIT_TIMEOUT;
-            break;
-        } else {
+        default:
             break;
         }
     }
-    pthread_mutex_unlock(&a_node_list_request->wait_mutex);
-    return a_node_list_request->response;
+    return pthread_mutex_unlock(&a_node_list_request->wait_mutex), a_node_list_request->response;
+#endif
 }
 
 static int s_cb_node_addr_compare(dap_list_t *a_list_elem, dap_list_t *a_addr_elem) {
@@ -258,10 +284,8 @@ int dap_chain_net_node_list_request(dap_chain_net_t *a_net, uint16_t a_port, boo
         return -1;
     
     struct node_link_request *l_link_node_request = s_node_list_request_init();
-    if (!l_link_node_request) {
-        log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-        return -4;
-    };
+    if (!l_link_node_request)
+        return log_it(L_CRITICAL, "%s", c_error_memory_alloc), -4;
 
     char *l_request = dap_strdup_printf( "%s/%s?version=1,method=%c,addr=%zu,port=%hu,net=%s",
                                          DAP_UPLINK_PATH_NODE_LIST, DAP_NODE_LIST_URI_HASH, a_cmd,
@@ -273,7 +297,7 @@ int dap_chain_net_node_list_request(dap_chain_net_t *a_net, uint16_t a_port, boo
         dap_chain_node_info_t *l_remote = dap_chain_node_info_read(a_net, l_seeds_addrs + i);
         if (!l_remote)
             continue;
-        if ( dap_client_http_request(l_link_node_request->worker, l_remote->ext_host, l_remote->ext_port,
+        if ( dap_client_http_request(dap_worker_get_auto(), l_remote->ext_host, l_remote->ext_port,
                                     "GET", "text/text", l_request, NULL, 0, NULL,
                                     s_net_node_link_prepare_success, s_net_node_link_prepare_error,
                                     l_link_node_request, NULL) )
@@ -311,9 +335,6 @@ int dap_chain_net_node_list_request(dap_chain_net_t *a_net, uint16_t a_port, boo
 
 int dap_chain_net_node_list_init()
 {
-    /*for (dap_chain_net_t *it = dap_chain_net_iter_start(); it; it = dap_chain_net_iter_next(it)) {
-        dap_chain_net_add_nodelist_notify_callback(it, s_node_list_callback_notify, it);
-    }*/
     return 0;
 }
 
diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c
index b632f9b9ad9067d09a65f122d1c9df5605217a3e..8c41bf81d19aea7f53c1d87f13daf154b5e894d2 100644
--- a/modules/net/dap_chain_node_cli_cmd.c
+++ b/modules/net/dap_chain_node_cli_cmd.c
@@ -566,8 +566,6 @@ int com_global_db(int a_argc, char ** a_argv, void **a_str_reply)
         switch (l_subcmd) {
             case SUMCMD_GET: // Get value
             {
-                char *l_hash_str;
-                dap_get_data_hash_str_static(l_value, l_value_len, l_hash_str);
                 char *l_value_str = DAP_NEW_Z_SIZE(char, l_value_len * 2 + 2);
                 if(!l_value_str) {
                     log_it(L_CRITICAL, "%s", c_error_memory_alloc);
@@ -580,7 +578,7 @@ int com_global_db(int a_argc, char ** a_argv, void **a_str_reply)
                 size_t ret = dap_bin2hex(l_value_str, l_value, l_value_len);
                 json_object_object_add(json_obj_rec, "command status", json_object_new_string("Record found"));
                 json_object_object_add(json_obj_rec, "lenght(byte)", json_object_new_uint64(l_value_len));
-                json_object_object_add(json_obj_rec, "hash", json_object_new_string(l_hash_str));
+                json_object_object_add(json_obj_rec, "hash", json_object_new_string(dap_get_data_hash_str(l_value, l_value_len).s));
                 json_object_object_add(json_obj_rec, "pinned", l_is_pinned ? json_object_new_string("Yes") : json_object_new_string("No") );
                 json_object_object_add(json_obj_rec, "value", json_object_new_string(l_value_str));
                 DAP_DELETE(l_value_str);
@@ -6820,9 +6818,8 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **reply)
 
     // Add transaction to mempool
     char *l_gdb_group_mempool_base_tx = dap_chain_net_get_gdb_group_mempool_new(l_chain);// get group name for mempool
-    char *l_tx_hash_str;
-    dap_get_data_hash_str_static(l_datum_tx->data, l_datum_tx->header.data_size, l_tx_hash_str);
-    bool l_placed = !dap_global_db_set(l_gdb_group_mempool_base_tx,l_tx_hash_str, l_datum_tx, l_datum_tx_size, false, NULL, NULL);
+    char *l_tx_hash_str = dap_get_data_hash_str(l_datum_tx->data, l_datum_tx->header.data_size).s;
+    bool l_placed = !dap_global_db_set(l_gdb_group_mempool_base_tx, l_tx_hash_str, l_datum_tx, l_datum_tx_size, false, NULL, NULL);
 
     DAP_DEL_Z(l_datum_tx);
     DAP_DELETE(l_gdb_group_mempool_base_tx);
@@ -8248,46 +8245,26 @@ static int s_signer_cmd(int a_arg_index, int a_argc, char **a_argv, void **a_str
         dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, l_opts_signer[i].name, (const char **) &l_opts_sign[i]);
     }
 
-    if (!l_opts_sign[OPT_CERT]) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "%s need to be selected", l_opts_signer[OPT_CERT].name);
-        return -1;
-    }
+    if (!l_opts_sign[OPT_CERT])
+        return dap_cli_server_cmd_set_reply_text(a_str_reply, "%s need to be selected", l_opts_signer[OPT_CERT].name), -1;
 
     dap_chain_net_t *l_network = dap_chain_net_by_name(l_opts_sign[OPT_NET]);
-    if (!l_network) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "%s network not found", l_opts_sign[OPT_NET]);
-        return -1;
-    }
+    if ( !l_network )
+        return dap_cli_server_cmd_set_reply_text(a_str_reply, "%s network not found", l_opts_sign[OPT_NET]), -1;
 
     dap_chain_t *l_chain = dap_chain_net_get_chain_by_name(l_network, l_opts_sign[OPT_CHAIN]);
-    if (!l_chain) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "%s chain not found", l_opts_sign[OPT_CHAIN]);
-        return -1;
-    }
+    if (!l_chain)
+        return dap_cli_server_cmd_set_reply_text(a_str_reply, "%s chain not found", l_opts_sign[OPT_CHAIN]), -1;
 
-    int l_ret = 0;
     dap_sign_t *l_sign = NULL;
-    dap_chain_datum_t *l_datum = NULL;
-
-    l_ret = s_get_key_from_file(l_opts_sign[OPT_FILE], l_opts_sign[OPT_MIME], l_opts_sign[OPT_CERT], &l_sign);
-    if (!l_ret) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "%s cert not found", l_opts_sign[OPT_CERT]);
-        return -1;
-    }
-
-    l_datum = dap_chain_datum_create(DAP_CHAIN_DATUM_SIGNER, l_sign->pkey_n_sign, l_sign->header.sign_size);
-    if (!l_datum) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "not created datum");
-        return -1;
-    }
-
-    l_ret = l_chain->callback_add_datums(l_chain, &l_datum, 1);
-
-    char *l_key_str;
-    dap_get_data_hash_str_static(l_datum->data, l_datum->header.data_size, l_key_str);
-    dap_cli_server_cmd_set_reply_text(a_str_reply, "hash: %s", l_key_str);
-    DAP_DELETE(l_datum);
-    return l_ret;
+    if ( !s_get_key_from_file(l_opts_sign[OPT_FILE], l_opts_sign[OPT_MIME], l_opts_sign[OPT_CERT], &l_sign) )
+        return dap_cli_server_cmd_set_reply_text(a_str_reply, "%s cert not found", l_opts_sign[OPT_CERT]), -1;
+
+    dap_chain_datum_t * l_datum = dap_chain_datum_create(DAP_CHAIN_DATUM_SIGNER, l_sign->pkey_n_sign, l_sign->header.sign_size);
+    if (!l_datum)
+        return dap_cli_server_cmd_set_reply_text(a_str_reply, "not created datum"), -1;
+    dap_cli_server_cmd_set_reply_text(a_str_reply, "hash: %s", dap_get_data_hash_str(l_datum->data, l_datum->header.data_size));
+    return DAP_DELETE(l_datum), l_chain->callback_add_datums(l_chain, &l_datum, 1);
 }
 
 
diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c
index ccd6b5fde52ff42cf7246287cc323393a6032aa1..09a098ebd29497710da77f2f0bbb67c549c9b3bf 100644
--- a/modules/net/dap_chain_node_cli_cmd_tx.c
+++ b/modules/net/dap_chain_node_cli_cmd_tx.c
@@ -652,7 +652,7 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain,
             SUM_256_256(l_corr_value, l_fee_sum, &l_corr_value);
             const char *l_coins_str, *l_value_str = dap_uint256_to_char(l_corr_value, &l_coins_str);
             json_object_object_add(l_corr_object, "recv_coins", json_object_new_string(l_coins_str));
-            json_object_object_add(l_corr_object, "recv_datoshi", json_object_new_string(l_value_str));            
+            json_object_object_add(l_corr_object, "recv_datoshi", json_object_new_string(l_value_str));
             json_object * j_arr_correct = json_object_new_object();            
             json_object_object_add(j_arr_correct, "correction", l_corr_object);
             json_object_array_add(json_obj_datum, j_arr_correct);
diff --git a/modules/net/include/dap_chain_ledger.h b/modules/net/include/dap_chain_ledger.h
index 6c5c487316371532bc920e335429b1b1a552f555..f4c28609100125802617db44e4e26717520edcdf 100644
--- a/modules/net/include/dap_chain_ledger.h
+++ b/modules/net/include/dap_chain_ledger.h
@@ -201,7 +201,8 @@ typedef struct dap_ledger_datum_iter {
 } dap_ledger_datum_iter_t;
 
 typedef int (*dap_ledger_verificator_callback_t)(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *a_tx_out_cond, dap_chain_datum_tx_t *a_tx_in, bool a_owner);
-typedef void (*dap_ledger_updater_callback_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_tx_out_cond_t *a_prev_cond);
+typedef void (*dap_ledger_updater_callback_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx_in, dap_hash_fast_t *a_tx_in_hash, dap_chain_tx_out_cond_t *a_prev_cond);
+typedef void (*dap_ledger_delete_callback_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx_in, dap_chain_tx_out_cond_t *a_prev_cond);
 typedef void (* dap_ledger_tx_add_notify_t)(void *a_arg, dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chan_ledger_notify_opcodes_t a_opcode);
 typedef void (* dap_ledger_bridged_tx_notify_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, void *a_arg, dap_chan_ledger_notify_opcodes_t a_opcode);
 typedef bool (*dap_ledger_cache_tx_check_callback_t)(dap_ledger_t *a_ledger, dap_hash_fast_t *a_tx_hash);
@@ -433,7 +434,7 @@ dap_list_t *dap_ledger_get_list_tx_cond_outs(dap_ledger_t *a_ledger, const char
                                              dap_chain_tx_out_cond_subtype_t a_subtype, uint256_t *a_value_transfer);
 // Add new verificator callback with associated subtype. Returns 1 if callback replaced, overwise returns 0
 int dap_ledger_verificator_add(dap_chain_tx_out_cond_subtype_t a_subtype, dap_ledger_verificator_callback_t a_callback,
-                                     dap_ledger_updater_callback_t a_callback_added, dap_ledger_updater_callback_t a_callback_deleted);
+                                     dap_ledger_updater_callback_t a_callback_added, dap_ledger_delete_callback_t a_callback_deleted);
 // Add new verificator callback for voting. Returns 1 if callback replaced, overwise returns 0
 int dap_chain_ledger_voting_verificator_add(dap_chain_ledger_voting_callback_t a_callback, dap_chain_ledger_voting_delete_callback_t a_callback_delete);
 // Getting a list of transactions from the ledger.
@@ -450,8 +451,9 @@ dap_chain_datum_tx_t *dap_ledger_datum_iter_get_last(dap_ledger_datum_iter_t *a_
 void dap_ledger_tx_add_notify(dap_ledger_t *a_ledger, dap_ledger_tx_add_notify_t a_callback, void *a_arg);
 void dap_ledger_bridged_tx_notify_add(dap_ledger_t *a_ledger, dap_ledger_bridged_tx_notify_t a_callback, void *a_arg);
 
+bool dap_ledger_datum_is_blacklisted(dap_ledger_t *a_ledger, dap_hash_fast_t a_hash);
 
 bool dap_ledger_cache_enabled(dap_ledger_t *a_ledger);
 void dap_ledger_set_cache_tx_check_callback(dap_ledger_t *a_ledger, dap_ledger_cache_tx_check_callback_t a_callback);
 dap_chain_tx_out_cond_t* dap_chain_ledger_get_tx_out_cond_linked_to_tx_in_cond(dap_ledger_t *a_ledger, dap_chain_tx_in_cond_t *a_in_cond);
-void dap_leger_load_end(dap_ledger_t *a_ledger);
+void dap_ledger_load_end(dap_ledger_t *a_ledger);
diff --git a/modules/net/include/dap_chain_net_balancer.h b/modules/net/include/dap_chain_net_balancer.h
index b5e1d0bd26bf0d06335676b698f41256e79895e7..ccada8e10d97086f34654e607c3113a8a5bde7c2 100644
--- a/modules/net/include/dap_chain_net_balancer.h
+++ b/modules/net/include/dap_chain_net_balancer.h
@@ -30,6 +30,8 @@ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/lic
 #define DAP_BALANCER_PROTOCOL_VERSION 2
 #define DAP_BALANCER_MAX_REPLY_SIZE 2048
 
+typedef struct dap_balancer_request_info dap_balancer_request_info_t;
+
 typedef struct dap_chain_net_links {
     uint64_t count_node;
     byte_t nodes_info[];
@@ -40,6 +42,15 @@ typedef enum dap_balancer_type {
     DAP_CHAIN_NET_BALANCER_TYPE_DNS
 } dap_balancer_type_t;
 
+typedef struct dap_balancer_link_request {
+    const char* host_addr;
+    uint16_t host_port;
+    dap_chain_net_t *net;
+    dap_worker_t *worker;
+    uint16_t required_links_count;
+    dap_balancer_request_info_t *request_info;
+    dap_balancer_type_t type;
+} dap_balancer_link_request_t;
 
 DAP_STATIC_INLINE const char *dap_chain_net_balancer_type_to_str(dap_balancer_type_t a_type)
 {
@@ -54,4 +65,4 @@ void dap_chain_net_balancer_http_issue_link(dap_http_simple_t *a_http_simple, vo
 dap_link_info_t *dap_chain_net_balancer_dns_issue_link(const char *a_net_name);
 int dap_chain_net_balancer_handshake(dap_chain_node_info_t *a_node_info, dap_chain_net_t * a_net);
 dap_string_t *dap_chain_net_balancer_get_node_str(dap_chain_net_t *a_net);
-int dap_chain_net_balancer_request(dap_chain_net_t *a_net, const char *a_host_addr, uint16_t a_host_port, int a_balancer_type);
\ No newline at end of file
+void dap_chain_net_balancer_request(void *a_arg);
\ No newline at end of file
diff --git a/modules/net/include/dap_chain_net_decree.h b/modules/net/include/dap_chain_net_decree.h
index 270db17d7677121195c387e3b85eced5c8c7bb23..6cf2e6eff0b9f651d0826fb6b678d18a25ac5f2d 100644
--- a/modules/net/include/dap_chain_net_decree.h
+++ b/modules/net/include/dap_chain_net_decree.h
@@ -36,7 +36,7 @@ int dap_chain_net_decree_deinit(dap_chain_net_t *a_net);
 
 void dap_chain_net_decree_purge(dap_chain_net_t *a_net);
 
-int dap_chain_net_decree_apply(dap_hash_fast_t *a_decree_hash, dap_chain_datum_decree_t * a_decree, dap_chain_t *a_chain);
+int dap_chain_net_decree_apply(dap_hash_fast_t *a_decree_hash, dap_chain_datum_decree_t * a_decree, dap_chain_t *a_chain, bool a_anchored);
 int dap_chain_net_decree_verify(dap_chain_net_t *a_net, dap_chain_datum_decree_t *a_decree, size_t a_data_size, dap_chain_hash_fast_t *a_decree_hash);
 int dap_chain_net_decree_load(dap_chain_datum_decree_t * a_decree, dap_chain_t *a_chain, dap_chain_hash_fast_t *a_decree_hash);
 dap_chain_datum_decree_t *dap_chain_net_decree_get_by_hash(dap_chain_net_t *a_net, dap_hash_fast_t *a_hash, bool *is_applied);
diff --git a/modules/net/include/dap_chain_net_node_list.h b/modules/net/include/dap_chain_net_node_list.h
index cacbd70f2cb535eabad94cd54c84c746067aab16..8fe6dd6b1b62ef57f0f31f2885210b454b1fa54c 100644
--- a/modules/net/include/dap_chain_net_node_list.h
+++ b/modules/net/include/dap_chain_net_node_list.h
@@ -32,18 +32,22 @@ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/lic
 struct node_link_request {
     dap_chain_node_info_t *link_info;
     dap_chain_net_t *net;
-    dap_worker_t *worker;
-    int link_replace_tries;
-    int response;
+#ifdef DAP_OS_WINDOWS
+    CONDITION_VARIABLE wait_cond;
+    CRITICAL_SECTION wait_crit_sec;
+#else
     pthread_cond_t wait_cond;
     pthread_mutex_t wait_mutex;
+#endif
+    int response;
 };
+
 /**
 * @brief dap_chain_net_node_list_get_gdb_group
 * @param a_net
 * @return
 */
-DAP_STATIC_INLINE char * dap_chain_net_node_list_get_gdb_group(dap_chain_net_t * a_net)
+DAP_STATIC_INLINE char* dap_chain_net_node_list_get_gdb_group(dap_chain_net_t * a_net)
 {
     return a_net ? dap_strdup_printf("%s.service.orders",a_net->pub.gdb_groups_prefix) : NULL;
 }
diff --git a/modules/service/stake/dap_chain_net_srv_stake_lock.c b/modules/service/stake/dap_chain_net_srv_stake_lock.c
index 53a216607537db1cbf3f2d8f92c4b1ea1852b6d6..7a5d72bcd9cf9762641eb2dd54eb296efec5856c 100644
--- a/modules/service/stake/dap_chain_net_srv_stake_lock.c
+++ b/modules/service/stake/dap_chain_net_srv_stake_lock.c
@@ -107,7 +107,7 @@ dap_chain_datum_t *s_stake_unlock_datum_create(dap_chain_net_t *a_net, dap_enc_k
                                                uint256_t a_value_fee,
                                                const char *a_delegated_ticker_str, uint256_t a_delegated_value,int *res);
 // Callbacks
-static void s_stake_lock_callback_updater(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_tx_out_cond_t *a_prev_out_item);
+static void s_stake_lock_callback_updater(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx_in, dap_hash_fast_t *a_tx_in_hash, dap_chain_tx_out_cond_t *a_prev_out_item);
 static int s_stake_lock_callback_verificator(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx_in, bool a_owner);
 
 static inline int s_tsd_str_cmp(const byte_t *a_tsdata, size_t a_tsdsize,  const char *str ) {
@@ -1043,10 +1043,8 @@ static int s_stake_lock_callback_verificator(dap_ledger_t *a_ledger, dap_chain_t
             if (!l_burning_tx) {
                 char l_burning_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE] = { '\0' };
                 dap_hash_fast_to_str(&l_burning_tx_hash, l_burning_tx_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE);
-                char *l_take_tx_hash_str;
-                dap_get_data_hash_str_static(a_tx_in, dap_chain_datum_tx_get_size(a_tx_in), l_take_tx_hash_str);
                 debug_if(s_debug_more, L_ERROR, "[Legacy] Can't find burning tx with hash %s, obtained from the receipt of take tx %s",
-                       l_burning_tx_hash_str, l_take_tx_hash_str);
+                                                l_burning_tx_hash_str, dap_get_data_hash_str(a_tx_in, dap_chain_datum_tx_get_size(a_tx_in)).s);
                 return -10;
             }
         } else
@@ -1105,17 +1103,14 @@ static int s_stake_lock_callback_verificator(dap_ledger_t *a_ledger, dap_chain_t
  * @param a_tx_item_idx
  * @return
  */
-static void s_stake_lock_callback_updater(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_tx_out_cond_t *a_prev_out_item)
+static void s_stake_lock_callback_updater(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx_in, dap_hash_fast_t *a_tx_in_hash, dap_chain_tx_out_cond_t *a_prev_out_item)
 {
     if (a_prev_out_item)  // this is IN_COND tx
         return;
     int l_out_num = 0;
-    dap_chain_tx_out_cond_t *l_cond = dap_chain_datum_tx_out_cond_get(a_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK, &l_out_num);
-    if (l_cond->subtype.srv_stake_lock.flags & DAP_CHAIN_NET_SRV_STAKE_LOCK_FLAG_CREATE_BASE_TX) {
-        dap_chain_hash_fast_t l_tx_cond_hash;
-        dap_hash_fast(a_tx, dap_chain_datum_tx_get_size(a_tx), &l_tx_cond_hash);
-        dap_ledger_emission_for_stake_lock_item_add(a_ledger, &l_tx_cond_hash);
-    }
+    dap_chain_tx_out_cond_t *l_cond = dap_chain_datum_tx_out_cond_get(a_tx_in, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK, &l_out_num);
+    if (l_cond->subtype.srv_stake_lock.flags & DAP_CHAIN_NET_SRV_STAKE_LOCK_FLAG_CREATE_BASE_TX)
+        dap_ledger_emission_for_stake_lock_item_add(a_ledger, a_tx_in_hash);
 }
 
 static dap_chain_datum_t *s_stake_lock_datum_create(dap_chain_net_t *a_net, dap_enc_key_t *a_key_from,
diff --git a/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c b/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c
index 2efa8490bfb650e3268f9e8e8e4595c6a79d508c..6ae42e529b82481abac1dc6d1753efeff1f19e62 100644
--- a/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c
+++ b/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c
@@ -50,7 +50,7 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply);
 
 static int s_stake_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *a_cond,
                                                       dap_chain_datum_tx_t *a_tx_in, bool a_owner);
-static void s_stake_updater_callback(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_tx_out_cond_t *a_cond);
+static void s_stake_updater_callback(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx_in, dap_hash_fast_t *a_tx_in_hash, dap_chain_tx_out_cond_t *a_cond);
 
 static void s_stake_deleted_callback(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_tx_out_cond_t *a_cond);
 
@@ -105,33 +105,34 @@ int dap_chain_net_srv_stake_pos_delegate_init()
                         " [-addr <for_tax_collecting>]  [-cert <for_order_signing>] [-H {hex(default) | base58}]\n"
         "\tCreates an order allowing the validator to delegate it's key with specified params\n"
     "srv_stake order update -net <net_name> -order <order_hash> [-params]\n"
-         "\tUpdates an order with specified hash\n"
+        "\tUpdates an order with specified hash\n"
     "srv_stake order list [fee | validator | staker] -net <net_name>\n"
-         "\tGet orders list of specified type within specified net name\n"
+        "\tGet orders list of specified type within specified net name\n"
     "srv_stake order remove -net <net_name> -order <order_hash>\n"
-         "\tRemove order with specified hash\n"
+        "\tRemove order with specified hash\n"
             "\t\t === Commands for work with stake delegate ===\n"
     "srv_stake delegate {-cert <pub_cert_name> -value <datoshi> | "
                                 "-order <order_hash> {[-tax_addr <wallet_addr_for_tax_collecting>] | "
                                         "-cert <priv_cert_name> [-node_addr <for_validator_node>]}}"
                         " -net <net_name> -w <wallet_name> -fee <value>\n"
-         "\tDelegate public key in specified certificate or order with specified net name. Pay with specified value of m-tokens of native net token.\n"
-    "srv_stake invalidate -net <net_name> {-tx <transaction_hash> | -cert <delegated_cert> | -siging_pkey_hash <pkey_hash> -signing_pkey_type <pkey_type>}"
-                            " {-w <wallet_name> -fee <value> | -poa_cert <cert_name>}\n"
-         "\tInvalidate requested delegated stake transaction by hash or cert name or cert pkey hash within net name and"
-         " return m-tokens to specified wallet (if any)\n"
+        "\tDelegate public key in specified certificate or order with specified net name. Pay with specified value of m-tokens of native net token.\n"
+    "srv_stake update -net <net_name> {-tx <transaction_hash> | -cert <delegated_cert>} -w <wallet_name> -value <new_delegation_value> -fee <value>\n"
+        "\tUpdate public key delegation value for specified certificate or transaction hash with specified net name. Pay or cacheback the difference of m-tokens of native net token.\n"
+    "srv_stake invalidate -net <net_name> {-tx <transaction_hash> -w <wallet_name> -fee <value> | -siging_pkey_hash <pkey_hash> -signing_pkey_type <pkey_type> -poa_cert <cert_name>}\n"
+        "\tInvalidate requested delegated stake transaction by hash or cert name or cert pkey hash within net name and"
+        " return m-tokens to specified wallet (if any)\n"
     "srv_stake approve -net <net_name> -tx <transaction_hash> -poa_cert <priv_cert_name>\n"
-         "\tApprove stake transaction by root node certificate within specified net name\n"
+        "\tApprove stake transaction by root node certificate within specified net name\n"
     "srv_stake list keys -net <net_name> [-cert <delegated_cert> | -pkey <pkey_hash_str>]\n"
-         "\tShow the list of active stake keys (optional delegated with specified cert).\n"
+        "\tShow the list of active stake keys (optional delegated with specified cert).\n"
     "srv_stake list tx -net <net_name> \n"
-         "\tShow the list of key delegation transactions.\n"
+        "\tShow the list of key delegation transactions.\n"
     "srv_stake min_value -net <net_name> [-chain <chain_name>] -poa_cert <poa_cert_name> -value <value>\n"
-         "\tSets the minimum stake value\n"
+        "\tSets the minimum stake value\n"
     "srv_stake max_weight -net <net_name> [-chain <chain_name>] -poa_cert <poa_cert_name> -percent <value>\n"
         "\tSets maximum validator related weight (in percent)\n"
     "srv_stake check -net <net_name> -tx <tx_hash>\n"
-         "\tCheck remote validator"
+        "\tCheck remote validator"
     );
 
     dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_ID };
@@ -202,75 +203,119 @@ void dap_chain_net_srv_stake_pos_delegate_deinit()
 static int s_stake_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *a_cond,
                                          dap_chain_datum_tx_t *a_tx_in, bool a_owner)
 {
+    dap_return_val_if_fail(a_ledger && a_cond && a_tx_in, -1);
     dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_ledger->net->pub.id);
-    dap_return_val_if_fail(l_srv_stake, -1);
+    dap_return_val_if_fail(l_srv_stake, -2);
+
+#define m_cond_check()                                                                              \
+(                                                                                                   \
+    {                                                                                               \
+        if (l_tx_new_cond->header.subtype != a_cond->header.subtype ||                              \
+                l_tx_new_cond->header.ts_expires != a_cond->header.ts_expires ||                    \
+                !dap_chain_net_srv_uid_compare(l_tx_new_cond->header.srv_uid,                       \
+                                               a_cond->header.srv_uid)                              \
+                ) {                                                                                 \
+            log_it(L_WARNING, "Conditional out and conditional in have different headers");         \
+            return -3;                                                                              \
+        }                                                                                           \
+        if (l_tx_new_cond->tsd_size != a_cond->tsd_size ||                                          \
+                memcmp(l_tx_new_cond->tsd, a_cond->tsd, a_cond->tsd_size)) {                        \
+            log_it(L_WARNING, "Conditional out and conditional in have different TSD sections");    \
+            return -4;                                                                              \
+        }                                                                                           \
+        if (dap_chain_addr_is_blank(&l_tx_new_cond->subtype.srv_stake_pos_delegate.signing_addr) || \
+                l_tx_new_cond->subtype.srv_stake_pos_delegate.signer_node_addr.uint64 == 0) {       \
+            log_it(L_WARNING, "Not blank address or key fields in order conditional tx");           \
+            return -5;                                                                              \
+        }                                                                                           \
+    }                                                                                               \
+)
+    int l_out_idx = 0;
+    dap_chain_tx_out_cond_t *l_tx_new_cond = dap_chain_datum_tx_out_cond_get(
+                                                a_tx_in, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE, &l_out_idx);
     // It's a order conditional TX
     if (dap_chain_addr_is_blank(&a_cond->subtype.srv_stake_pos_delegate.signing_addr) ||
             a_cond->subtype.srv_stake_pos_delegate.signer_node_addr.uint64 == 0) {
         if (a_owner)
             return 0;
-        int l_out_idx = 0;
-        dap_chain_tx_out_cond_t *l_tx_out_cond = dap_chain_datum_tx_out_cond_get(a_tx_in, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE, &l_out_idx);
-        if (!l_tx_out_cond) {
+        if (!l_tx_new_cond) {
             log_it(L_ERROR, "Condition not found in conditional tx");
-            return -2;
-        }
-        if (compare256(l_tx_out_cond->header.value, a_cond->header.value)) {
-            char *l_in_value = dap_chain_balance_to_coins(l_tx_out_cond->header.value);
-            char *l_out_value = dap_chain_balance_to_coins(a_cond->header.value);
-            log_it(L_WARNING, "In value %s is not equal to out value %s", l_in_value, l_out_value);
-            DAP_DELETE(l_in_value);
-            DAP_DELETE(l_out_value);
-            return -3;
-        }
-        if (l_tx_out_cond->tsd_size != a_cond->tsd_size ||
-                memcmp(l_tx_out_cond->tsd, a_cond->tsd, a_cond->tsd_size)) {
-            log_it(L_WARNING, "Conditional out and conditional in have different TSD sections");
-            return -4;
+            return -13;
         }
-        if (dap_chain_addr_is_blank(&l_tx_out_cond->subtype.srv_stake_pos_delegate.signing_addr) ||
-                l_tx_out_cond->subtype.srv_stake_pos_delegate.signer_node_addr.uint64 == 0) {
-            log_it(L_WARNING, "Not blank address or key fields in order conditional tx");
-            return -5;
+        m_cond_check();
+
+        if (compare256(l_tx_new_cond->header.value, a_cond->header.value)) {
+            log_it(L_WARNING, "Conditional out and conditional in have different values");
+            return -14;
         }
         return 0;
     }
-    // It's a delegation conitional TX
-    dap_chain_tx_in_cond_t *l_tx_in_cond = (dap_chain_tx_in_cond_t *)dap_chain_datum_tx_item_get(a_tx_in, NULL, NULL, TX_ITEM_TYPE_IN_COND, NULL);
-    if (!l_tx_in_cond) {
-        log_it(L_ERROR, "Conditional in item not found in checking tx");
-        return -6;
-    }
-    // ATTENTION: It's correct only with single IN_COND TX item
-    dap_hash_fast_t *l_prev_hash = &l_tx_in_cond->header.tx_prev_hash;
-    if (dap_hash_fast_is_blank(l_prev_hash)) {
-        log_it(L_ERROR, "Blank hash of prev tx in tx_in_cond");
-        return -7;
-    }
     if (!a_owner) {
-        log_it(L_WARNING, "Trying to spend conditional tx not by owner");
+        log_it(L_WARNING, "Trying to spend conditional tx by not a owner");
         return -11;
     }
-    if (a_tx_in->header.ts_created < 1706227200) // Jan 26 2024 00:00:00 GMT, old policy rules
-        return 0;
-    dap_chain_net_srv_stake_item_t *l_stake = NULL;
-    HASH_FIND(ht, l_srv_stake->tx_itemlist, l_prev_hash, sizeof(dap_hash_t), l_stake);
-    if (l_stake) {
-        log_it(L_WARNING, "Key is active with delegation decree, need to revoke it first");
-        return -12;
+    // Delegation value update (dynamic weight feature)
+    if (l_tx_new_cond) {
+
+        m_cond_check();
+
+        if (!dap_chain_addr_compare(&l_tx_new_cond->subtype.srv_stake_pos_delegate.signing_addr,
+                                    &a_cond->subtype.srv_stake_pos_delegate.signing_addr)) {
+            log_it(L_WARNING, "Conditional out and conditional in have different signer key hashes");
+            return -15;
+        }
+        if (l_tx_new_cond->subtype.srv_stake_pos_delegate.signer_node_addr.uint64 !=
+                a_cond->subtype.srv_stake_pos_delegate.signer_node_addr.uint64) {
+            log_it(L_WARNING, "Conditional out and conditional in have different node addresses");
+            return -16;
+        }
+        if (compare256(l_tx_new_cond->header.value,
+                       dap_chain_net_srv_stake_get_allowed_min_value(a_ledger->net->pub.id)) == -1) {
+            log_it(L_WARNING, "New conditional out have value %s lower than minimum service required",
+                                                    dap_uint256_to_char(l_tx_new_cond->header.value, NULL));
+            return -17;
+        }
+    } else {
+        // It's a delegation conitional TX
+        dap_chain_tx_in_cond_t *l_tx_in_cond = (dap_chain_tx_in_cond_t *)
+                                                dap_chain_datum_tx_item_get(a_tx_in, NULL, NULL, TX_ITEM_TYPE_IN_COND, NULL);
+        if (!l_tx_in_cond) {
+            log_it(L_ERROR, "Conditional in item not found in current tx");
+            return -6;
+        }
+        // ATTENTION: It's correct only with single IN_COND TX item
+        dap_hash_fast_t *l_prev_hash = &l_tx_in_cond->header.tx_prev_hash;
+        if (dap_hash_fast_is_blank(l_prev_hash)) {
+            log_it(L_ERROR, "Blank hash of prev tx in tx_in_cond");
+            return -7;
+        }
+        if (a_tx_in->header.ts_created < 1706227200) // Jan 26 2024 00:00:00 GMT, old policy rules
+            return 0;
+        dap_chain_net_srv_stake_item_t *l_stake = NULL;
+        HASH_FIND(ht, l_srv_stake->tx_itemlist, l_prev_hash, sizeof(dap_hash_t), l_stake);
+        if (l_stake) {
+            log_it(L_WARNING, "Key %s is empowered for now, need to revoke it first",
+                                    dap_hash_fast_to_str_static(&l_stake->signing_addr.data.hash_fast));
+            return -12;
+        }
     }
     return 0;
 }
 
-static void s_stake_updater_callback(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_tx_out_cond_t *a_cond)
+static void s_stake_updater_callback(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx_in, dap_hash_fast_t *a_tx_in_hash, dap_chain_tx_out_cond_t *a_cond)
 {
+    dap_return_if_fail(a_ledger && a_tx_in);
     dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_ledger->net->pub.id);
     dap_return_if_fail(l_srv_stake);
     if (!a_cond)
         return;
+    dap_chain_tx_out_cond_t *l_tx_new_cond = dap_chain_datum_tx_out_cond_get(a_tx_in, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE, NULL);
     dap_chain_addr_t *l_signing_addr = &a_cond->subtype.srv_stake_pos_delegate.signing_addr;
-    dap_chain_net_srv_stake_key_invalidate(l_signing_addr);
-    s_cache_data(a_ledger, a_tx, l_signing_addr);
+    if (l_tx_new_cond)
+        dap_chain_net_srv_stake_key_update(l_signing_addr, l_tx_new_cond->header.value, a_tx_in_hash);
+    else
+        dap_chain_net_srv_stake_key_invalidate(l_signing_addr);
+    s_cache_data(a_ledger, a_tx_in, l_signing_addr);
 }
 
 static void s_stake_deleted_callback(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_tx_out_cond_t *a_cond)
@@ -327,6 +372,7 @@ static bool s_weights_truncate(dap_chain_net_srv_stake_t *l_srv_stake, const uin
     }
     return l_exceeds_count;
 }
+#undef LIMIT_DELTA
 
 static void s_stake_recalculate_weights(dap_chain_net_id_t a_net_id)
 {
@@ -384,35 +430,49 @@ void dap_chain_net_srv_stake_key_delegate(dap_chain_net_t *a_net, dap_chain_addr
         }
     }
     dap_chain_esbocs_add_validator_to_clusters(a_net->pub.id, a_node_addr);
-    char l_key_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
-    dap_chain_hash_fast_to_str(&a_signing_addr->data.hash_fast,
-                               l_key_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE);
     const char *l_value_str; dap_uint256_to_char(a_value, &l_value_str);
-    log_it(L_NOTICE, "Added key with fingerprint %s and locked value %s for node "NODE_ADDR_FP_STR,
-                        l_key_hash_str, l_value_str, NODE_ADDR_FP_ARGS(a_node_addr));
+    log_it(L_NOTICE, "Added key with fingerprint %s and locked value %s for node " NODE_ADDR_FP_STR,
+                            dap_chain_hash_fast_to_str_static(&a_signing_addr->data.hash_fast), l_value_str, NODE_ADDR_FP_ARGS(a_node_addr));
     s_stake_recalculate_weights(a_signing_addr->net_id);
 }
 
 void dap_chain_net_srv_stake_key_invalidate(dap_chain_addr_t *a_signing_addr)
 {
-    if (!a_signing_addr)
-        return;
+    dap_return_if_fail(a_signing_addr);
     dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_signing_addr->net_id);
     dap_return_if_fail(l_srv_stake);
     dap_chain_net_srv_stake_item_t *l_stake = NULL;
     HASH_FIND(hh, l_srv_stake->itemlist, &a_signing_addr->data.hash_fast, sizeof(dap_hash_fast_t), l_stake);
-    if (l_stake) {
-        dap_chain_esbocs_remove_validator_from_clusters(l_stake->signing_addr.net_id, &l_stake->node_addr);
-        HASH_DEL(l_srv_stake->itemlist, l_stake);
-        HASH_DELETE(ht, l_srv_stake->tx_itemlist, l_stake);
-        char l_key_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
-        dap_chain_hash_fast_to_str(&a_signing_addr->data.hash_fast,
-                                   l_key_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE);
-        const char *l_value_str; dap_uint256_to_char(l_stake->locked_value, &l_value_str);
-        log_it(L_NOTICE, "Removed key with fingerprint %s and locked value %s for node "NODE_ADDR_FP_STR,
-                            l_key_hash_str, l_value_str, NODE_ADDR_FP_ARGS_S(l_stake->node_addr));
-        DAP_DELETE(l_stake);
-    }
+    dap_return_if_fail(l_stake);
+    dap_chain_esbocs_remove_validator_from_clusters(l_stake->signing_addr.net_id, &l_stake->node_addr);
+    HASH_DEL(l_srv_stake->itemlist, l_stake);
+    HASH_DELETE(ht, l_srv_stake->tx_itemlist, l_stake);
+    const char *l_value_str; dap_uint256_to_char(l_stake->locked_value, &l_value_str);
+    log_it(L_NOTICE, "Removed key with fingerprint %s and locked value %s for node " NODE_ADDR_FP_STR,
+                            dap_chain_hash_fast_to_str_static(&a_signing_addr->data.hash_fast), l_value_str, NODE_ADDR_FP_ARGS_S(l_stake->node_addr));
+    DAP_DELETE(l_stake);
+    s_stake_recalculate_weights(a_signing_addr->net_id);
+}
+
+void dap_chain_net_srv_stake_key_update(dap_chain_addr_t *a_signing_addr, uint256_t a_new_value, dap_hash_fast_t *a_new_tx_hash)
+{
+    dap_return_if_fail(a_signing_addr && a_new_tx_hash);
+    dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_signing_addr->net_id);
+    dap_return_if_fail(l_srv_stake);
+    dap_chain_net_srv_stake_item_t *l_stake = NULL;
+    HASH_FIND(hh, l_srv_stake->itemlist, &a_signing_addr->data.hash_fast, sizeof(dap_hash_fast_t), l_stake);
+    if (!l_stake)
+        return; // It's update for non delegated key, it's OK
+    HASH_DELETE(ht, l_srv_stake->tx_itemlist, l_stake);
+    l_stake->locked_value = l_stake->value = a_new_value;
+    l_stake->tx_hash = *a_new_tx_hash;
+    HASH_ADD(ht, l_srv_stake->tx_itemlist, tx_hash, sizeof(dap_hash_fast_t), l_stake);
+    char *l_old_value_str = dap_chain_balance_to_coins(l_stake->locked_value);
+    const char *l_new_value_str; dap_uint256_to_char(a_new_value, &l_new_value_str);
+    log_it(L_NOTICE, "Updated key with fingerprint %s and locked value %s to new locked value %s for node " NODE_ADDR_FP_STR,
+                            dap_chain_hash_fast_to_str_static(&a_signing_addr->data.hash_fast), l_old_value_str,
+                                l_new_value_str, NODE_ADDR_FP_ARGS_S(l_stake->node_addr));
+    DAP_DELETE(l_old_value_str);
     s_stake_recalculate_weights(a_signing_addr->net_id);
 }
 
@@ -423,7 +483,7 @@ void dap_chain_net_srv_stake_set_allowed_min_value(dap_chain_net_id_t a_net_id,
     l_srv_stake->delegate_allowed_min = a_value;
     for (dap_chain_net_srv_stake_item_t *it = l_srv_stake->itemlist; it; it = it->hh.next)
         if (dap_hash_fast_is_blank(&it->tx_hash))
-            it->value = a_value;
+            it->locked_value = it->value = a_value;
 }
 
 void dap_chain_net_srv_stake_set_percent_max(dap_chain_net_id_t a_net_id, uint256_t a_value)
@@ -655,7 +715,7 @@ static dap_chain_datum_tx_t *s_stake_tx_create(dap_chain_net_t * a_net, dap_enc_
                                                                            &l_owner_addr, a_value, &l_value_transfer);
         if (!l_list_used_out) {
             log_it(L_WARNING, "Nothing to pay for delegate (not enough funds)");
-            return NULL;
+            goto tx_fail;
         }
         // add 'in' items to pay for delegate
         uint256_t l_value_to_items = dap_chain_datum_tx_add_in_item_list(&l_tx, l_list_used_out);
@@ -741,6 +801,134 @@ tx_fail:
     return NULL;
 }
 
+// Updates staker's funds with delegated key
+static dap_chain_datum_tx_t *s_stake_tx_update(dap_chain_net_t *a_net, dap_hash_fast_t *a_prev_tx_hash, uint256_t a_new_value, uint256_t a_fee, dap_enc_key_t *a_key)
+{
+    dap_return_val_if_fail(a_net && a_key && a_prev_tx_hash && !IS_ZERO_256(a_new_value), NULL);
+
+    const char *l_native_ticker = a_net->pub.native_ticker;
+    char l_delegated_ticker[DAP_CHAIN_TICKER_SIZE_MAX];
+    dap_chain_datum_token_get_delegated_ticker(l_delegated_ticker, l_native_ticker);
+    dap_ledger_t *l_ledger = dap_ledger_by_net_name(a_net->pub.name);
+    uint256_t l_value_transfer = {}, l_fee_transfer = {}; // how many coins to transfer
+    // list of transaction with 'out' items to sell
+    dap_chain_addr_t l_owner_addr;
+    dap_chain_addr_fill_from_key(&l_owner_addr, a_key, a_net->pub.id);
+    uint256_t l_net_fee, l_fee_total = a_fee;
+    dap_chain_addr_t l_net_fee_addr;
+    bool l_net_fee_used = dap_chain_net_tx_get_fee(a_net->pub.id, &l_net_fee, &l_net_fee_addr);
+    if (l_net_fee_used)
+        SUM_256_256(l_fee_total, l_net_fee, &l_fee_total);
+    dap_list_t *l_list_fee_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker,
+                                                                      &l_owner_addr, l_fee_total, &l_fee_transfer);
+    if (!l_list_fee_out) {
+        log_it(L_WARNING, "Nothing to pay for fee (not enough funds)");
+        return NULL;
+    }
+    dap_chain_datum_tx_t *l_tx_prev = dap_ledger_tx_find_by_hash(l_ledger, a_prev_tx_hash);
+    if (!l_tx_prev) {
+        log_it(L_ERROR, "Transaction %s not found", dap_hash_fast_to_str_static(a_prev_tx_hash));
+        return NULL;
+    }
+    int l_out_num = 0;
+    dap_chain_tx_out_cond_t *l_cond_prev = dap_chain_datum_tx_out_cond_get(l_tx_prev, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE, &l_out_num);
+    if (!l_cond_prev) {
+        log_it(L_ERROR, "Transaction %s is invalid", dap_hash_fast_to_str_static(a_prev_tx_hash));
+        return NULL;
+    }
+
+    // create empty transaction
+    dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create();
+
+    // add 'in' item to buy from conditional transaction
+    if (1 != dap_chain_datum_tx_add_in_cond_item(&l_tx, a_prev_tx_hash, l_out_num, -1)) {
+        log_it(L_ERROR, "Can't compose the transaction conditional input");
+        goto tx_fail;
+    }
+
+    // add 'in' items to pay fee
+    uint256_t l_value_fee_items = dap_chain_datum_tx_add_in_item_list(&l_tx, l_list_fee_out);
+    dap_list_free_full(l_list_fee_out, NULL);
+    if (!EQUAL_256(l_value_fee_items, l_fee_transfer)) {
+        log_it(L_ERROR, "Can't compose the fee transaction input");
+        goto tx_fail;
+    }
+    uint256_t l_value_prev = l_cond_prev->header.value, l_value_back = {};
+    bool l_increasing = compare256(a_new_value, l_value_prev) == 1;
+    if (l_increasing) {
+        uint256_t l_refund_value = {};
+        SUBTRACT_256_256(a_new_value, l_value_prev, &l_refund_value);
+        dap_list_t *l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, l_delegated_ticker,
+                                                                           &l_owner_addr, l_refund_value, &l_value_transfer);
+        if (!l_list_used_out) {
+            log_it(L_WARNING, "Nothing to pay for delegate (not enough funds)");
+            return NULL;
+        }
+        // add 'in' items to pay for delegate
+        uint256_t l_value_to_items = dap_chain_datum_tx_add_in_item_list(&l_tx, l_list_used_out);
+        dap_list_free_full(l_list_used_out, NULL);
+        if (!EQUAL_256(l_value_to_items, l_value_transfer)) {
+            log_it(L_ERROR, "Can't compose the transaction input");
+            goto tx_fail;
+        }
+        SUBTRACT_256_256(l_value_transfer, l_refund_value, &l_value_back);
+    } else
+        SUBTRACT_256_256(l_value_prev, a_new_value, &l_value_back);
+
+    // add 'out_cond' & 'out_ext' items
+    dap_chain_tx_out_cond_t *l_out_cond = DAP_DUP_SIZE(l_cond_prev, sizeof(dap_chain_tx_out_cond_t) + l_cond_prev->tsd_size);
+    if (!l_out_cond) {
+        log_it(L_CRITICAL, "%s", c_error_memory_alloc);
+        goto tx_fail;
+    }
+    l_out_cond->header.value = a_new_value;
+    dap_chain_datum_tx_add_item(&l_tx, (const uint8_t *)l_out_cond);
+    DAP_DELETE(l_out_cond);
+
+    // coin back
+    if (!IS_ZERO_256(l_value_back)) {
+        if (dap_chain_datum_tx_add_out_ext_item(&l_tx, &l_owner_addr, l_value_back, l_delegated_ticker) != 1) {
+            log_it(L_ERROR, "Cant add coin back output");
+            goto tx_fail;
+        }
+    }
+
+    // add fee items
+    if (l_net_fee_used) {
+        if (dap_chain_datum_tx_add_out_ext_item(&l_tx, &l_net_fee_addr, l_net_fee, l_native_ticker) != 1) {
+            log_it(L_ERROR, "Cant add net fee output");
+            goto tx_fail;
+        }
+    }
+    if (!IS_ZERO_256(a_fee)) {
+        if (dap_chain_datum_tx_add_fee_item(&l_tx, a_fee) != 1) {
+            log_it(L_ERROR, "Cant add validator fee output");
+            goto tx_fail;
+        }
+    }
+    uint256_t l_fee_back = {};
+    // fee coin back
+    SUBTRACT_256_256(l_fee_transfer, l_fee_total, &l_fee_back);
+    if (!IS_ZERO_256(l_fee_back)) {
+        if (dap_chain_datum_tx_add_out_ext_item(&l_tx, &l_owner_addr, l_fee_back, l_native_ticker) != 1) {
+            log_it(L_ERROR, "Cant add fee back output");
+            goto tx_fail;
+        }
+    }
+
+    // add 'sign' item
+    if (dap_chain_datum_tx_add_sign_item(&l_tx, a_key) != 1) {
+        log_it(L_ERROR, "Can't add sign output");
+        goto tx_fail;
+    }
+
+    return l_tx;
+
+tx_fail:
+    dap_chain_datum_tx_delete(l_tx);
+    return NULL;
+}
+
 static dap_chain_datum_tx_t *s_order_tx_create(dap_chain_net_t * a_net, dap_enc_key_t *a_key,
                                                uint256_t a_value, uint256_t a_fee,
                                                 uint256_t a_sovereign_tax, dap_chain_addr_t *a_sovereign_addr)
@@ -799,10 +987,6 @@ dap_chain_datum_decree_t *dap_chain_net_srv_stake_decree_approve(dap_chain_net_t
         log_it(L_WARNING, "Requested conditional transaction have another ticker (not %s)", l_delegated_ticker);
         return NULL;
     }
-    if (compare256(l_tx_out_cond->header.value, dap_chain_net_srv_stake_get_allowed_min_value(a_net->pub.id)) == -1) {
-        log_it(L_WARNING, "Requested conditional transaction have not enough funds");
-        return NULL;
-    }
 
     if(dap_chain_net_srv_stake_verify_key_and_node(&l_tx_out_cond->subtype.srv_stake_pos_delegate.signing_addr, &l_tx_out_cond->subtype.srv_stake_pos_delegate.signer_node_addr)){
         log_it(L_WARNING, "Key and node verification error");
@@ -1896,7 +2080,7 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index,
     uint256_t l_allowed_min = dap_chain_net_srv_stake_get_allowed_min_value(l_net->pub.id);
     if (compare256(l_value, l_allowed_min) == -1) {
         const char *l_coin_min_str, *l_value_min_str = dap_uint256_to_char(l_allowed_min, &l_coin_min_str);
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Number in '-value' param %s is lower than minimum allowed value %s(%s)",
+        dap_cli_server_cmd_set_reply_text(a_str_reply, "Number in '-value' param %s is lower than service minimum allowed value %s(%s)",
                                           l_value_str, l_coin_min_str, l_value_min_str);
         dap_enc_key_delete(l_enc_key);
         return -11;
@@ -1931,13 +2115,149 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index,
     return 0;
 }
 
+static int s_cli_srv_stake_update(int a_argc, char **a_argv, int a_arg_index, void **a_str_reply, const char *a_hash_out_type)
+{
+    const char *l_net_str = NULL,
+               *l_wallet_str = NULL,
+               *l_value_str,
+               *l_fee_str = NULL,
+               *l_tx_hash_str = NULL,
+               *l_cert_str = NULL;
+    dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-net", &l_net_str);
+    if (!l_net_str) {
+        dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'update' requires parameter -net");
+        return -3;
+    }
+    dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str);
+    if (!l_net) {
+        dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str);
+        return -4;
+    }
+    uint256_t l_fee = {};
+    dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-w", &l_wallet_str);
+    if (!l_wallet_str) {
+        dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'update' requires parameter -w");
+        return -17;
+    }
+    dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-fee", &l_fee_str);
+    if (!l_fee_str) {
+        dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'update' requires parameter -fee");
+        return -5;
+    }
+    l_fee = dap_chain_balance_scan(l_fee_str);
+    if (IS_ZERO_256(l_fee)) {
+        dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized number in '-fee' param");
+        return -6;
+    }
+    uint256_t l_value = {};
+    dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-value", &l_value_str);
+    if (!l_value_str) {
+        dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'update' requires parameter -value");
+        return -7;
+    }
+    l_value = dap_chain_balance_scan(l_value_str);
+    if (IS_ZERO_256(l_value)) {
+        dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized number in '-value' param");
+        return -8;
+    }
+    uint256_t l_value_min = dap_chain_net_srv_stake_get_allowed_min_value(l_net->pub.id);
+    if (compare256(l_value, l_value_min) == -1) {
+        const char *l_value_min_str; dap_uint256_to_char(l_value_min, &l_value_min_str);
+        dap_cli_server_cmd_set_reply_text(a_str_reply, "New delegation value should be not less than service required minimum %s", l_value_min_str);
+        return -25;
+    }
+
+    dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-tx", &l_tx_hash_str);
+    if (!l_tx_hash_str) {
+        dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-cert", &l_cert_str);
+        if (!l_cert_str) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'update' requires parameter -tx or -cert");
+            return -13;
+        }
+    }
+    dap_hash_fast_t l_tx_hash = {};
+    if (l_tx_hash_str) {
+        dap_chain_hash_fast_from_str(l_tx_hash_str, &l_tx_hash);
+    } else {
+        dap_chain_addr_t l_signing_addr;
+        dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_str);
+        if (!l_cert) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate not found");
+            return -18;
+        }
+        if (!l_cert->enc_key->priv_key_data || l_cert->enc_key->priv_key_data_size == 0) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "It is not possible to update a stake using a public key.");
+            return -31;
+        }
+        if (dap_chain_addr_fill_from_key(&l_signing_addr, l_cert->enc_key, l_net->pub.id)) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate is wrong");
+            return -22;
+        }
+        dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(l_net->pub.id);
+        if (!l_srv_stake) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified net have no stake service activated");
+            return -25;
+        }
+        dap_chain_net_srv_stake_item_t *l_stake = NULL;
+        HASH_FIND(hh, l_srv_stake->itemlist, &l_signing_addr.data.hash_fast, sizeof(dap_hash_fast_t), l_stake);
+        if (!l_stake) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate/pkey hash is not delegated nor this delegating is approved."
+                                                           " Try to update with tx hash instead");
+            return -24;
+        }
+        l_tx_hash = l_stake->tx_hash;
+    }
+
+    const char *l_tx_hash_str_tmp = l_tx_hash_str ? l_tx_hash_str : dap_hash_fast_to_str_static(&l_tx_hash);
+    dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_tx_hash);
+    if (!l_tx) {
+        dap_cli_server_cmd_set_reply_text(a_str_reply, "Transaction %s not found", l_tx_hash_str_tmp);
+        return -21;
+    }
+    int l_out_num = 0;
+    if (!dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE, &l_out_num)) {
+        dap_cli_server_cmd_set_reply_text(a_str_reply, "Transaction %s is invalid", l_tx_hash_str_tmp);
+        return -22;
+    }
+    dap_hash_fast_t l_spender_hash = {};
+    if (dap_ledger_tx_hash_is_used_out_item(l_net->pub.ledger, &l_tx_hash, l_out_num, &l_spender_hash)) {
+        dap_cli_server_cmd_set_reply_text(a_str_reply, "Transaction %s is spent", l_tx_hash_str_tmp);
+        return -23;
+    }
+
+    const char* l_sign_str = "";
+    dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_str, dap_chain_wallet_get_path(g_config), NULL);
+    if (!l_wallet) {
+        dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified wallet %s not found", l_wallet_str);
+        return -18;
+    } else {
+        l_sign_str = dap_chain_wallet_check_sign(l_wallet);
+    }
+    dap_enc_key_t *l_enc_key = dap_chain_wallet_get_key(l_wallet, 0);
+    dap_chain_datum_tx_t *l_tx_new = s_stake_tx_update(l_net, &l_tx_hash, l_value, l_fee, l_enc_key);
+    dap_chain_wallet_close(l_wallet);
+    dap_enc_key_delete(l_enc_key);
+    char *l_out_hash_str = NULL;
+    if (l_tx_new && (l_out_hash_str = s_stake_tx_put(l_tx_new, l_net, a_hash_out_type))) {
+        dap_cli_server_cmd_set_reply_text(a_str_reply, "%sDelegated m-tokens value will change. Updating tx hash is %s.", l_sign_str, l_out_hash_str);
+        DAP_DELETE(l_out_hash_str);
+        DAP_DELETE(l_tx_new);
+    } else {
+        l_tx_hash_str = dap_chain_hash_fast_to_str_static(&l_tx_hash);
+        dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't compose updating transaction %s, examine log files for details", l_tx_hash_str);
+        DAP_DEL_Z(l_tx_new);
+        return -21;
+    }
+    return 0;
+}
+
+
 static int s_cli_srv_stake_invalidate(int a_argc, char **a_argv, int a_arg_index, void **a_str_reply, const char *a_hash_out_type)
 {
     const char *l_net_str = NULL,
                *l_wallet_str = NULL,
                *l_fee_str = NULL,
                *l_tx_hash_str = NULL,
-               *l_cert_str = NULL,
                *l_poa_cert_str = NULL,
                *l_signing_pkey_hash_str = NULL,
                *l_signing_pkey_type_str = NULL;
@@ -1962,7 +2282,7 @@ static int s_cli_srv_stake_invalidate(int a_argc, char **a_argv, int a_arg_index
     } else {
         dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-fee", &l_fee_str);
         if (!l_fee_str) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'delegate' requires parameter -fee");
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'invalidate' requires parameter -fee");
             return -5;
         }
         l_fee = dap_chain_balance_scan(l_fee_str);
@@ -1973,22 +2293,19 @@ static int s_cli_srv_stake_invalidate(int a_argc, char **a_argv, int a_arg_index
     }
     dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-tx", &l_tx_hash_str);
     if (!l_tx_hash_str) {
-        dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-cert", &l_cert_str);
-        if (!l_cert_str) {
-            dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-signing_pkey_hash", &l_signing_pkey_hash_str);
-            if (!l_signing_pkey_hash_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'invalidate' requires parameter -tx or -cert or -signing_pkey_hash");
-                return -13;
-            }
-            dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-signing_pkey_type", &l_signing_pkey_type_str);
-            if (!l_signing_pkey_type_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'invalidate' requires parameter -signing_pkey_type");
-                return -14;
-            }
-            if (dap_sign_type_from_str(l_signing_pkey_type_str).type == SIG_TYPE_NULL) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Invalid signing_pkey_type %s", l_signing_pkey_type_str);
-                return -15;
-            }
+        dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-signing_pkey_hash", &l_signing_pkey_hash_str);
+        if (!l_signing_pkey_hash_str) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'invalidate' requires parameter -tx or -signing_pkey_hash");
+            return -13;
+        }
+        dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-signing_pkey_type", &l_signing_pkey_type_str);
+        if (!l_signing_pkey_type_str) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'invalidate' requires parameter -signing_pkey_type");
+            return -14;
+        }
+        if (dap_sign_type_from_str(l_signing_pkey_type_str).type == SIG_TYPE_NULL) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Invalid signing_pkey_type %s", l_signing_pkey_type_str);
+            return -15;
         }
     }
 
@@ -1996,29 +2313,13 @@ static int s_cli_srv_stake_invalidate(int a_argc, char **a_argv, int a_arg_index
     if (l_tx_hash_str) {
         dap_chain_hash_fast_from_str(l_tx_hash_str, &l_tx_hash);
     } else {
-        dap_chain_addr_t l_signing_addr;
-        if (l_cert_str) {
-            dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_str);
-            if (!l_cert) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate not found");
-                return -18;
-            }
-            if (!l_cert->enc_key->priv_key_data || l_cert->enc_key->priv_key_data_size == 0) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "It is not possible to invalidate a stake using a public key.");
-                return -31;
-            }
-            if (dap_chain_addr_fill_from_key(&l_signing_addr, l_cert->enc_key, l_net->pub.id)) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate is wrong");
-                return -22;
-            }
-        } else {
-            dap_hash_fast_t l_pkey_hash = {};
-            if (dap_chain_hash_fast_from_str(l_signing_pkey_hash_str, &l_pkey_hash)) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Invalid pkey hash format");
-                return -23;
-            }
-            dap_chain_addr_fill(&l_signing_addr, dap_sign_type_from_str(l_signing_pkey_type_str), &l_pkey_hash, l_net->pub.id);
+        dap_hash_fast_t l_pkey_hash = {};
+        if (dap_chain_hash_fast_from_str(l_signing_pkey_hash_str, &l_pkey_hash)) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Invalid pkey hash format");
+            return -23;
         }
+        dap_chain_addr_t l_signing_addr;
+        dap_chain_addr_fill(&l_signing_addr, dap_sign_type_from_str(l_signing_pkey_type_str), &l_pkey_hash, l_net->pub.id);
         dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(l_net->pub.id);
         if (!l_srv_stake) {
             dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified net have no stake service activated");
@@ -2048,14 +2349,10 @@ static int s_cli_srv_stake_invalidate(int a_argc, char **a_argv, int a_arg_index
     }
     dap_hash_fast_t l_spender_hash = {};
     if (dap_ledger_tx_hash_is_used_out_item(l_net->pub.ledger, &l_tx_hash, l_out_num, &l_spender_hash)) {
-        l_tx_hash = l_spender_hash;
-        l_tx_hash_str_tmp = dap_hash_fast_to_str_static(&l_spender_hash);
-        if (!dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_tx_hash)) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Previous transaction %s is not found", l_tx_hash_str_tmp);
-            return -21;
-        }
+        dap_cli_server_cmd_set_reply_text(a_str_reply, "Transaction %s is spent", l_tx_hash_str_tmp);
+        return -23;
     }
-    if (l_tx_hash_str || l_cert_str) {
+    if (l_tx_hash_str) {
         dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(l_net->pub.id);
         if (!l_srv_stake) {
             dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified net have no stake service activated");
@@ -2087,13 +2384,13 @@ static int s_cli_srv_stake_invalidate(int a_argc, char **a_argv, int a_arg_index
         dap_enc_key_delete(l_enc_key);
         char *l_out_hash_str = NULL;
         if (l_tx && (l_out_hash_str = s_stake_tx_put(l_tx, l_net, a_hash_out_type))) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "%sAll m-tokens successfully returned to "
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "%sAll m-tokens will be returned to "
                                                            "owner. Returning tx hash %s.", l_sign_str, l_out_hash_str);
             DAP_DELETE(l_out_hash_str);
             DAP_DELETE(l_tx);
         } else {
             l_tx_hash_str = dap_chain_hash_fast_to_str_static(&l_tx_hash);
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't invalidate transaction %s, examine log files for details", l_tx_hash_str);
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't compose invalidation transaction %s, examine log files for details", l_tx_hash_str);
             DAP_DEL_Z(l_tx);
             return -21;
         }
@@ -2131,7 +2428,8 @@ static void s_srv_stake_print(dap_chain_net_srv_stake_item_t *a_stake, uint256_t
     char l_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE], l_pkey_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
     dap_chain_hash_fast_to_str(&a_stake->tx_hash, l_tx_hash_str, sizeof(l_tx_hash_str));
     dap_chain_hash_fast_to_str(&a_stake->signing_addr.data.hash_fast, l_pkey_hash_str, sizeof(l_pkey_hash_str));
-    char *l_balance = dap_chain_balance_to_coins(a_stake->value);
+    char *l_balance = dap_chain_balance_to_coins(a_stake->locked_value);
+    char *l_effective_weight = dap_chain_balance_to_coins(a_stake->value);
     uint256_t l_rel_weight, l_tmp;
     MULT_256_256(a_stake->value, GET_256_FROM_64(100), &l_tmp);
     DIV_256_COIN(l_tmp, a_total_weight, &l_rel_weight);
@@ -2146,16 +2444,18 @@ static void s_srv_stake_print(dap_chain_net_srv_stake_item_t *a_stake, uint256_t
     char *l_sov_tax_str = dap_chain_balance_to_coins(l_sov_tax_percent);
     dap_string_append_printf(a_string, "Pkey hash: %s\n"
                                         "\tStake value: %s\n"
+                                        "\tEffective value: %s\n"
                                         "\tRelated weight: %s%%\n"
                                         "\tTx hash: %s\n"
                                         "\tNode addr: "NODE_ADDR_FP_STR"\n"
                                         "\tSovereign addr: %s\n"
                                         "\tSovereign tax: %s%%\n"
                                         "%s\n",
-                             l_pkey_hash_str, l_balance, l_rel_weight_str,
+                             l_pkey_hash_str, l_balance, l_effective_weight, l_rel_weight_str,
                              l_tx_hash_str, NODE_ADDR_FP_ARGS_S(a_stake->node_addr),
                              l_sov_addr_str, l_sov_tax_str, l_active_str);
     DAP_DELETE(l_balance);
+    DAP_DELETE(l_effective_weight);
     DAP_DELETE(l_rel_weight_str);
     DAP_DELETE(l_sov_tax_str);
 }
@@ -2298,7 +2598,7 @@ int dap_chain_net_srv_stake_check_validator(dap_chain_net_t * a_net, dap_hash_fa
     return l_overall_correct;
 }
 
-uint256_t dap_chain_net_srv_stake_get_total_weight(dap_chain_net_id_t a_net_id)
+uint256_t dap_chain_net_srv_stake_get_total_weight(dap_chain_net_id_t a_net_id, uint256_t *a_locked_weight)
 {
     dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net_id);
     dap_return_val_if_fail(l_srv_stake, uint256_0);
@@ -2307,6 +2607,8 @@ uint256_t dap_chain_net_srv_stake_get_total_weight(dap_chain_net_id_t a_net_id)
         if (it->signing_addr.net_id.uint64 != a_net_id.uint64)
             continue;
         SUM_256_256(l_total_weight, it->value, &l_total_weight);
+        if (a_locked_weight)
+            SUM_256_256(*a_locked_weight, it->locked_value, a_locked_weight);
     }
     return l_total_weight;
 }
@@ -2314,7 +2616,7 @@ uint256_t dap_chain_net_srv_stake_get_total_weight(dap_chain_net_id_t a_net_id)
 static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply)
 {
     enum {
-        CMD_NONE, CMD_ORDER, CMD_DELEGATE, CMD_APPROVE, CMD_LIST, CMD_INVALIDATE, CMD_MIN_VALUE, CMD_CHECK, CMD_MAX_WEIGHT
+        CMD_NONE, CMD_ORDER, CMD_DELEGATE, CMD_UPDATE, CMD_APPROVE, CMD_LIST, CMD_INVALIDATE, CMD_MIN_VALUE, CMD_CHECK, CMD_MAX_WEIGHT
     };
     int l_arg_index = 1;
 
@@ -2334,6 +2636,10 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply)
     else if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, dap_min(a_argc, l_arg_index + 1), "delegate", NULL)) {
         l_cmd_num = CMD_DELEGATE;
     }
+    // Create tx to change staker's funds for delegated key (if any)
+    else if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, dap_min(a_argc, l_arg_index + 1), "update", NULL)) {
+        l_cmd_num = CMD_UPDATE;
+    }
     // Create tx to approve staker's funds freeze
     else if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, dap_min(a_argc, l_arg_index + 1), "approve", NULL)) {
         l_cmd_num = CMD_APPROVE;
@@ -2365,6 +2671,9 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply)
         case CMD_DELEGATE:
             return s_cli_srv_stake_delegate(a_argc, a_argv, l_arg_index + 1, a_str_reply, l_hash_out_type);
 
+        case CMD_UPDATE:
+            return s_cli_srv_stake_update(a_argc, a_argv, l_arg_index + 1, a_str_reply, l_hash_out_type);
+
         case CMD_INVALIDATE:
             return s_cli_srv_stake_invalidate(a_argc, a_argv, l_arg_index + 1, a_str_reply, l_hash_out_type);
 
@@ -2555,7 +2864,7 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply)
 
                 dap_string_t *l_reply_str = dap_string_new("");
                 size_t l_inactive_count = 0, l_total_count = 0;
-                uint256_t l_total_weight = dap_chain_net_srv_stake_get_total_weight(l_net->pub.id);
+                uint256_t l_total_locked_weight = {}, l_total_weight = dap_chain_net_srv_stake_get_total_weight(l_net->pub.id, &l_total_locked_weight);
                 if (l_stake)
                     s_srv_stake_print(l_stake, l_total_weight, l_reply_str);
                 else
@@ -2572,9 +2881,10 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply)
                         dap_string_append_printf(l_reply_str, "Total keys count: %zu\n", l_total_count);
                     if (dap_chain_esbocs_started(l_net->pub.id))
                         dap_string_append_printf(l_reply_str, "Inactive keys count: %zu\n", l_inactive_count);
-                    const char *l_total_weight_coins, *l_total_weight_str =
-                            dap_uint256_to_char(l_total_weight, &l_total_weight_coins);
+                    const char *l_total_weight_coins, *l_total_weight_str = dap_uint256_to_char(l_total_locked_weight, &l_total_weight_coins);
                     dap_string_append_printf(l_reply_str, "Total weight: %s (%s)\n", l_total_weight_coins, l_total_weight_str);
+                    l_total_weight_str = dap_uint256_to_char(l_total_weight, &l_total_weight_coins);
+                    dap_string_append_printf(l_reply_str, "Total effective weight: %s (%s)\n", l_total_weight_coins, l_total_weight_str);
                 }
 
                 const char *l_delegate_min_str; dap_uint256_to_char(dap_chain_net_srv_stake_get_allowed_min_value(l_net->pub.id),
diff --git a/modules/service/stake/include/dap_chain_net_srv_stake_pos_delegate.h b/modules/service/stake/include/dap_chain_net_srv_stake_pos_delegate.h
index 19ca297c30461b77eaabcba70e1fca5096f64dfe..00449f6e4980fd11f0fd7f25267b6a68e5975594 100644
--- a/modules/service/stake/include/dap_chain_net_srv_stake_pos_delegate.h
+++ b/modules/service/stake/include/dap_chain_net_srv_stake_pos_delegate.h
@@ -72,6 +72,7 @@ int dap_chain_net_srv_stake_net_add(dap_chain_net_id_t a_net_id);
 void dap_chain_net_srv_stake_key_delegate(dap_chain_net_t *a_net, dap_chain_addr_t *a_signing_addr, dap_hash_fast_t *a_stake_tx_hash,
                                           uint256_t a_value, dap_chain_node_addr_t *a_node_addr);
 void dap_chain_net_srv_stake_key_invalidate(dap_chain_addr_t *a_signing_addr);
+void dap_chain_net_srv_stake_key_update(dap_chain_addr_t *a_signing_addr, uint256_t a_new_value, dap_hash_fast_t *a_new_tx_hash);
 void dap_chain_net_srv_stake_set_allowed_min_value(dap_chain_net_id_t a_net_id, uint256_t a_value);
 uint256_t dap_chain_net_srv_stake_get_allowed_min_value(dap_chain_net_id_t a_net_id);
 void dap_chain_net_srv_stake_set_percent_max(dap_chain_net_id_t a_net_id, uint256_t a_value);
@@ -98,5 +99,5 @@ dap_chain_datum_decree_t *dap_chain_net_srv_stake_decree_approve(dap_chain_net_t
 int dap_chain_net_srv_stake_mark_validator_active(dap_chain_addr_t *a_signing_addr, bool a_on_off);
 
 dap_chain_net_srv_stake_item_t *dap_chain_net_srv_stake_check_pkey_hash(dap_chain_net_id_t a_net_id, dap_hash_fast_t *a_pkey_hash);
-uint256_t dap_chain_net_srv_stake_get_total_weight(dap_chain_net_id_t a_net_id);
+uint256_t dap_chain_net_srv_stake_get_total_weight(dap_chain_net_id_t a_net_id, uint256_t *a_locked_weight);
 size_t dap_chain_net_srv_stake_get_total_keys(dap_chain_net_id_t a_net_id, size_t *a_in_active_count);
diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 42cea326359093a8f25eeb79c879444c329ebb39..7e8c19c190c14370b73f1ad8b1a185f8ffa95cd0 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -1795,7 +1795,8 @@ static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str,
     xchange_tx_type_t l_tx_type = dap_chain_net_srv_xchange_tx_get_type(a_net->pub.ledger, a_tx, &l_out_cond_item, &l_cond_idx, &l_out_prev_cond_item);
 
     bool l_is_closed = dap_ledger_tx_hash_is_used_out_item(a_net->pub.ledger, &l_tx_hash, l_cond_idx, NULL);
-    if ((a_filter_by_status == TX_STATUS_ACTIVE && l_is_closed) || (a_filter_by_status == TX_STATUS_INACTIVE && !l_is_closed))
+    if ((a_filter_by_status == TX_STATUS_ACTIVE && l_is_closed) || (a_filter_by_status == TX_STATUS_INACTIVE && !l_is_closed)
+     || (a_filter_by_status == TX_STATUS_ACTIVE && l_tx_type == TX_TYPE_INVALIDATE))
         return false;
 
     if(l_out_prev_cond_item && l_out_prev_cond_item->header.subtype != DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE)
diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c
index 0b76090d0f15515fc5362c0e5996f22da9e20602..a0feca9322aeb6f880bc3fb2371735949987a467 100644
--- a/modules/type/blocks/dap_chain_cs_blocks.c
+++ b/modules/type/blocks/dap_chain_cs_blocks.c
@@ -471,12 +471,11 @@ static void s_cli_meta_hash_print(json_object* a_json_obj_out, const char *a_met
  */
 static void s_cli_meta_hex_print(json_object* a_json_obj_out, const char * a_meta_title, dap_chain_block_meta_t * a_meta)
 {
-    char *l_data_hex = DAP_NEW_Z_SIZE(char, a_meta->hdr.data_size * 2 + 3);
-    dap_bin2hex(l_data_hex, a_meta->data, a_meta->hdr.data_size);
-    char l_tmp_buff[70]={0};
-    sprintf(l_tmp_buff,"0x%s\n", l_data_hex);
-    json_object_object_add(a_json_obj_out, a_meta_title, json_object_new_string(l_tmp_buff));
-    DAP_DELETE(l_data_hex);
+    int l_len = a_meta->hdr.data_size * 2 + 5;
+    char *l_str = DAP_NEW_STACK_SIZE(char, l_len);
+    snprintf(l_str, 2, "0x");
+    dap_bin2hex(l_str + 2, a_meta->data, a_meta->hdr.data_size);
+    json_object_object_add(a_json_obj_out, a_meta_title, json_object_new_string(l_str));
 }
 
 static void s_print_autocollect_table(dap_chain_net_t *a_net, json_object *a_json_obj_out, const char *a_table_name)
@@ -498,9 +497,9 @@ static void s_print_autocollect_table(dap_chain_net_t *a_net, json_object *a_jso
         json_object_array_add(json_arr_out, json_obj_t);
         SUM_256_256(l_total_value, l_cur_value, &l_total_value);
     }
-    char l_tmp_buff[256];
-    sprintf(l_tmp_buff,"Autocollect tables content for === %s ===", a_table_name);
-    json_object_object_add(a_json_obj_out, l_tmp_buff, json_arr_out);
+    char *l_val = dap_strdup_printf("Autocollect tables content for === %s ===", a_table_name);
+    json_object_object_add(a_json_obj_out, l_val, json_arr_out);
+    DAP_DEL_Z(l_val);
     if (l_objs_count) {
         dap_global_db_objs_delete(l_objs, l_objs_count);
         uint256_t l_collect_fee = dap_chain_esbocs_get_fee(a_net->pub.id);
@@ -522,14 +521,13 @@ static void s_print_autocollect_table(dap_chain_net_t *a_net, json_object *a_jso
         char *l_profit_str = dap_chain_balance_to_coins(l_collect_value);
         char *l_tax_str = dap_chain_balance_to_coins(l_collect_tax);
         char *l_fee_str = dap_chain_balance_to_coins(l_collect_fee);
-        sprintf(l_tmp_buff,"Total prepared value: %s %s, where profit is %s, tax is %s, fee is %s\n",
+        l_val = dap_strdup_printf("Total prepared value: %s %s, where profit is %s, tax is %s, fee is %s\n",
                                  l_total_str, a_net->pub.native_ticker, l_profit_str, l_tax_str, l_fee_str);
         DAP_DEL_MULTY(l_total_str, l_profit_str, l_tax_str, l_fee_str);
-    } else
-        strcpy(l_tmp_buff, "Empty");
-    char l_status_buf[32];
-    sprintf(l_status_buf, "%s status", a_table_name);
-    json_object_object_add(a_json_obj_out, l_status_buf, json_object_new_string(l_tmp_buff));
+    }
+    char *l_key = dap_strdup_printf("%s status", a_table_name);
+    json_object_object_add(a_json_obj_out, l_key, json_object_new_string(l_val ? l_val : "Empty"));
+    DAP_DEL_MULTY(l_key, l_val);
 }
 
 /**
@@ -710,20 +708,20 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
                 return DAP_CHAIN_NODE_CLI_COM_BLOCK_FIND_ERR;
             }
             dap_chain_block_t *l_block = l_block_cache->block;
-            char l_tmp_buff[70]={0};
 
-            char l_time_buf[DAP_TIME_STR_SIZE];    
-            dap_time_to_str_rfc822(l_time_buf, DAP_TIME_STR_SIZE, l_block->hdr.ts_created);
+            char l_time_buf[DAP_TIME_STR_SIZE], l_hexbuf[32] = { '\0' };
             // Header
             json_object* json_obj_inf = json_object_new_object();
             json_object_object_add(json_obj_inf, "Block number", json_object_new_uint64(l_block_cache->block_number));
             json_object_object_add(json_obj_inf, "hash", json_object_new_string(l_subcmd_str_arg));
-            sprintf(l_tmp_buff,"0x%04X",l_block->hdr.version);
-            json_object_object_add(json_obj_inf, "version", json_object_new_string(l_tmp_buff));
-            sprintf(l_tmp_buff,"0x%016"DAP_UINT64_FORMAT_X"",l_block->hdr.cell_id.uint64);
-            json_object_object_add(json_obj_inf, "cell_id", json_object_new_string(l_tmp_buff));
-            sprintf(l_tmp_buff,"0x%016"DAP_UINT64_FORMAT_X"",l_block->hdr.chain_id.uint64);
-            json_object_object_add(json_obj_inf, "chain_id", json_object_new_string(l_tmp_buff));
+            sprintf(l_hexbuf,"0x%04X",l_block->hdr.version);
+            
+            json_object_object_add(json_obj_inf, "version", json_object_new_string(l_hexbuf));
+            sprintf(l_hexbuf,"0x%016"DAP_UINT64_FORMAT_X"",l_block->hdr.cell_id.uint64);
+            json_object_object_add(json_obj_inf, "cell_id", json_object_new_string(l_hexbuf));
+            sprintf(l_hexbuf,"0x%016"DAP_UINT64_FORMAT_X"",l_block->hdr.chain_id.uint64);
+            json_object_object_add(json_obj_inf, "chain_id", json_object_new_string(l_hexbuf));
+            dap_time_to_str_rfc822(l_time_buf, DAP_TIME_STR_SIZE, l_block->hdr.ts_created);
             json_object_object_add(json_obj_inf, "ts_created", json_object_new_string(l_time_buf));
 
             // Dump Metadata
@@ -754,14 +752,13 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
                     s_cli_meta_hex_print(json_obj_meta, "NONCE2", l_meta);
                     break;
                 default: {
-                        char * l_data_hex = DAP_NEW_Z_SIZE(char,l_meta->hdr.data_size*2+3);
-                        dap_bin2hex(l_data_hex, l_meta->data, l_meta->hdr.data_size);
-                        sprintf(l_tmp_buff,"0x%0X",i);
-                        json_object_object_add(json_obj_meta, "# -", json_object_new_string(l_tmp_buff));
-                        sprintf(l_tmp_buff,"0x%s",l_data_hex);
-                        json_object_object_add(json_obj_meta, "Data hex - ", json_object_new_string(l_tmp_buff));
-                        DAP_DELETE(l_data_hex);
-                    }
+                    sprintf(l_hexbuf, "0x%0X", i);
+                    json_object_object_add(json_obj_meta, "# -", json_object_new_string(l_hexbuf));
+                    int l_len = l_meta->hdr.data_size * 2 + 5;
+                    char *l_data_hex = DAP_NEW_STACK_SIZE(char, l_len);
+                    snprintf(l_data_hex, 2, "0x");
+                    dap_bin2hex(l_data_hex + 2, l_meta->data, l_meta->hdr.data_size);
+                    json_object_object_add(json_obj_meta, "Data hex - ", json_object_new_string(l_data_hex)); }
                 }
                 json_object_array_add(json_arr_meta_out, json_obj_meta);
                 l_offset += sizeof(l_meta->hdr) + l_meta->hdr.data_size;
@@ -772,7 +769,6 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
             json_object_array_add(*json_arr_reply, json_obj_datum);
             json_object* json_arr_datum_out = json_object_new_array();
             for (uint32_t i=0; i < l_block_cache->datum_count ; i++){
-                char buf[70];
                 json_object* json_obj_tx = json_object_new_object();
                 dap_chain_datum_t * l_datum = l_block_cache->datum[i];
                 size_t l_datum_size =  dap_chain_datum_size(l_datum);
@@ -783,13 +779,13 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
                     break;
                 }
                 // Nested datums
-                sprintf(l_tmp_buff,"0x%02X",l_datum->header.version_id);
-                json_object_object_add(json_obj_tx, "version",json_object_new_string(l_tmp_buff));
-                const char * l_datum_type_str="UNKNOWN";
+                sprintf(l_hexbuf,"0x%02X",l_datum->header.version_id);
+                json_object_object_add(json_obj_tx, "version",json_object_new_string(l_hexbuf));
+                const char * l_datum_type_str = "UNKNOWN";
                 DAP_DATUM_TYPE_STR(l_datum->header.type_id, l_datum_type_str);
                 json_object_object_add(json_obj_tx, "type_id",json_object_new_string(l_datum_type_str));
-                dap_time_to_str_rfc822(buf, DAP_TIME_STR_SIZE, l_datum->header.ts_create);
-                json_object_object_add(json_obj_tx, "ts_create",json_object_new_string(buf));
+                dap_time_to_str_rfc822(l_time_buf, DAP_TIME_STR_SIZE, l_datum->header.ts_create);
+                json_object_object_add(json_obj_tx, "ts_create",json_object_new_string(l_time_buf));
                 json_object_object_add(json_obj_tx, "data_size",json_object_new_int(l_datum->header.data_size));
                 dap_chain_datum_dump_json(json_obj_tx,l_datum,l_hash_out_type,l_net->pub.id);
                 json_object_array_add(json_arr_datum_out, json_obj_tx);
@@ -824,8 +820,6 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
             dap_pkey_t * l_pub_key = NULL;
             dap_hash_fast_t l_from_hash = {}, l_to_hash = {}, l_pkey_hash = {};
             dap_time_t l_from_time = 0, l_to_time = 0;
-            char l_tmp_buff[150]={0};
-
             l_signed_flag = dap_cli_server_cmd_check_option(a_argv, 1, a_argc, "signed") > 0;
             l_first_signed_flag = dap_cli_server_cmd_check_option(a_argv, 1, a_argc, "first_signed") > 0;
             l_unspent_flag = dap_cli_server_cmd_check_option(a_argv, 1, a_argc, "-unspent") > 0;
@@ -996,12 +990,12 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
             json_object* json_obj_out = json_object_new_object();
             if (l_cert_name || l_pkey_hash_str || l_from_hash_str || l_to_hash_str || l_from_date_str || l_to_date_str)
                 l_filtered_criteria = " filtered according to the specified criteria";
-            sprintf(l_tmp_buff,"%s.%s with filter - %s, have blocks",l_net->pub.name,l_chain->name,l_filtered_criteria);
-            json_object_object_add(json_obj_out, l_tmp_buff, json_object_new_uint64(i_tmp));
+            char *l_key = dap_strdup_printf("%s.%s with filter - %s, have blocks",l_net->pub.name,l_chain->name,l_filtered_criteria);
+            json_object_object_add(json_obj_out, l_key, json_object_new_uint64(i_tmp));
+            DAP_DELETE(l_key);
             json_object_array_add(*json_arr_reply,json_obj_out);
         } break;
         case SUBCMD_LAST: {
-            char l_tmp_buff[70]={0};
             json_object* json_obj_out = json_object_new_object();
             dap_chain_block_cache_t *l_last_block = HASH_LAST(PVT(l_blocks)->blocks);
             char l_buf[DAP_TIME_STR_SIZE];
@@ -1011,8 +1005,9 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
             json_object_object_add(json_obj_out, "Last block hash", json_object_new_string(l_last_block ? l_last_block->block_hash_str : "empty"));
             json_object_object_add(json_obj_out, "ts_created", json_object_new_string(l_last_block ? l_buf : "never"));
 
-            sprintf(l_tmp_buff,"%s.%s has blocks", l_net->pub.name, l_chain->name);
-            json_object_object_add(json_obj_out, l_tmp_buff, json_object_new_uint64(PVT(l_blocks)->blocks_count));
+            char *l_key = dap_strdup_printf("%s.%s has blocks", l_net->pub.name, l_chain->name);
+            json_object_object_add(json_obj_out, l_key, json_object_new_uint64(PVT(l_blocks)->blocks_count));
+            DAP_DELETE(l_key);
             json_object_array_add(*json_arr_reply, json_obj_out);
         } break;
         case SUBCMD_FIND: {
@@ -1045,10 +1040,10 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
             json_object_array_add(*json_arr_reply, json_obj_out);
         } break;
         case SUBCMD_COUNT: {
-            char l_tmp_buff[70]={0};
             json_object* json_obj_out = json_object_new_object();
-            sprintf(l_tmp_buff,"%s.%s has blocks - ",l_net->pub.name,l_chain->name);
-            json_object_object_add(json_obj_out, l_tmp_buff, json_object_new_uint64(PVT(l_blocks)->blocks_count));
+            char *l_key = dap_strdup_printf("%s.%s has blocks - ", l_net->pub.name,l_chain->name);
+            json_object_object_add(json_obj_out, l_key, json_object_new_uint64(PVT(l_blocks)->blocks_count));
+            DAP_DELETE(l_key);
             json_object_array_add(*json_arr_reply, json_obj_out);
 
         } break;
@@ -1060,7 +1055,6 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
             const char * l_addr_str = NULL;
             const char * l_hash_out_type = NULL;
             const char * l_hash_str = NULL;
-            char l_tmp_buff[70]={0};
 
             uint256_t               l_fee_value = {};
             size_t                  l_hashes_count = 0;
@@ -1098,9 +1092,13 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
                     }
                     char *l_decree_hash_str = s_blocks_decree_set_reward(l_net, l_chain, l_value, l_cert);
                     if (l_decree_hash_str) {
-                        //добавить вывод
-                        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_OK, "Decree with hash %s created to set basic block sign reward", l_decree_hash_str);
+                        //dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_OK, "Decree with hash %s created to set basic block sign reward", l_decree_hash_str);
+                        json_object* json_obj_out = json_object_new_object();
+                        char *l_val = dap_strdup_printf("Decree with hash %s created to set basic block sign reward", l_decree_hash_str);
                         DAP_DELETE(l_decree_hash_str);
+                        json_object_object_add(json_obj_out, "status", json_object_new_string(l_val));
+                        DAP_DELETE(l_val);
+                        json_object_array_add(*json_arr_reply, json_obj_out);
                     } else {
                         dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_SIGN_ERR, "Basic block sign reward setting failed. Examine log file for details");
                         return DAP_CHAIN_NODE_CLI_COM_BLOCK_SIGN_ERR;
@@ -1110,8 +1108,9 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
                     uint256_t l_cur_reward = dap_chain_net_get_reward(l_net, UINT64_MAX);
                     const char *l_reward_str; dap_uint256_to_char(l_cur_reward, &l_reward_str);
                     json_object* json_obj_out = json_object_new_object();
-                    sprintf(l_tmp_buff,"Current base block reward is %s\n", l_reward_str);
-                    json_object_object_add(json_obj_out, "status", json_object_new_string(l_tmp_buff));
+                    char *l_val = dap_strdup_printf("Current base block reward is %s\n", l_reward_str);
+                    json_object_object_add(json_obj_out, "status", json_object_new_string(l_val));
+                    DAP_DELETE(l_val);
                     json_object_array_add(*json_arr_reply, json_obj_out);
                     break;
                 } else if (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "collect") == -1) {
@@ -1177,15 +1176,14 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
                 return DAP_CHAIN_NODE_CLI_COM_BLOCK_HASH_ERR;
             }
 
-            char *l_hash_tx = NULL;
-            if (l_subcmd == SUBCMD_FEE)
-                l_hash_tx = dap_chain_mempool_tx_coll_fee_create(l_blocks, l_cert->enc_key, l_addr, l_block_list, l_fee_value, l_hash_out_type);
-            else
-                l_hash_tx = dap_chain_mempool_tx_reward_create(l_blocks, l_cert->enc_key, l_addr, l_block_list, l_fee_value, l_hash_out_type);
+            char *l_hash_tx = l_subcmd == SUBCMD_FEE
+                ? dap_chain_mempool_tx_coll_fee_create(l_blocks, l_cert->enc_key, l_addr, l_block_list, l_fee_value, l_hash_out_type)
+                : dap_chain_mempool_tx_reward_create(l_blocks, l_cert->enc_key, l_addr, l_block_list, l_fee_value, l_hash_out_type);
             if (l_hash_tx) {
                 json_object* json_obj_out = json_object_new_object();
-                sprintf(l_tmp_buff, "TX for %s collection created successfully, hash = %s\n", l_subcmd_str, l_hash_tx);
-                json_object_object_add(json_obj_out, "status", json_object_new_string(l_tmp_buff));
+                char *l_val = dap_strdup_printf(l_val, "TX for %s collection created successfully, hash = %s\n", l_subcmd_str, l_hash_tx);
+                json_object_object_add(json_obj_out, "status", json_object_new_string(l_val));
+                DAP_DELETE(l_val);
                 json_object_array_add(*json_arr_reply, json_obj_out);
                 DAP_DELETE(l_hash_tx);
             } else {
@@ -1200,7 +1198,6 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
             const char *l_cert_name = NULL, *l_addr_str = NULL;
             dap_hash_fast_t l_pkey_hash = {};
             size_t l_block_count = 0;
-            char l_tmp_buff[128]={0};
             if (dap_cli_server_cmd_check_option(a_argv, arg_index,a_argc, "renew") > 0) {
                 dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-cert", &l_cert_name);
                 if(!l_cert_name) {
@@ -1277,8 +1274,9 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
                             char l_buf[DAP_TIME_STR_SIZE];
                             json_object* json_obj_bl = json_object_new_object();
                             dap_time_to_str_rfc822(l_buf, DAP_TIME_STR_SIZE, l_ts);
-                            sprintf(l_tmp_buff, "fee - \t%s: ts_create=%s\n", l_block_cache->block_hash_str, l_buf);
-                            json_object_object_add(json_obj_bl, "block", json_object_new_string(l_tmp_buff));
+                            char *l_val = dap_strdup_printf("fee - \t%s: ts_create=%s\n", l_block_cache->block_hash_str, l_buf);
+                            json_object_object_add(json_obj_bl, "block", json_object_new_string(l_val));
+                            DAP_DELETE(l_val);
                             json_object_array_add(json_arr_bl_out, json_obj_bl);
                             l_block_count++;
                             break;
@@ -1308,18 +1306,20 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
                     char l_buf[DAP_TIME_STR_SIZE];
                     json_object* json_obj_bl = json_object_new_object();
                     dap_time_to_str_rfc822(l_buf, DAP_TIME_STR_SIZE, l_ts);
-                    sprintf(l_tmp_buff, "rewards - \t%s: ts_create=%s\n", l_block_cache->block_hash_str, l_buf);
-                    json_object_object_add(json_obj_bl, "block", json_object_new_string(l_tmp_buff));
+                    char *l_val = dap_strdup_printf("rewards - \t%s: ts_create=%s\n", l_block_cache->block_hash_str, l_buf);
+                    json_object_object_add(json_obj_bl, "block", json_object_new_string(l_val));
+                    DAP_DELETE(l_val);
                     json_object_array_add(json_arr_bl_out, json_obj_bl);
                     l_block_count++;
                 }
                 json_object_array_add(*json_arr_reply, json_arr_bl_out);
                 json_object* json_obj_out = json_object_new_object();
-                sprintf(l_tmp_buff, "%s.%s: Have %"DAP_UINT64_FORMAT_U" blocks\n",
+                char *l_val = dap_strdup_printf("%s.%s: Have %"DAP_UINT64_FORMAT_U" blocks\n",
                                      l_net->pub.name, l_chain->name, l_block_count);
-                json_object_object_add(json_obj_out, "status", json_object_new_string(l_tmp_buff));
+                json_object_object_add(json_obj_out, "status", json_object_new_string(l_val));
+                DAP_DELETE(l_val);
                 json_object_array_add(*json_arr_reply, json_obj_out);
-            }else{
+            } else {
                 if (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "status") == -1) {
                     dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR,
                                             "Command 'block autocollect' requires subcommand 'status'");
@@ -1328,10 +1328,10 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
                 json_object* json_obj_out = json_object_new_object();
                 json_object_array_add(*json_arr_reply, json_obj_out);
                 bool l_status = dap_chain_esbocs_get_autocollect_status(l_net->pub.id);
-                char l_tmp_buff[150]={0};
-                sprintf(l_tmp_buff, "for network %s is %s\n", l_net->pub.name,
-                                                    l_status ? "active" : "inactive, cause the network config or consensus starting problems");
-                json_object_object_add(json_obj_out, "Autocollect status", json_object_new_string(l_tmp_buff));
+                char *l_val = dap_strdup_printf("for network %s is %s\n", l_net->pub.name,
+                                                l_status ? "active" : "inactive cause of the network config or consensus starting problems");
+                json_object_object_add(json_obj_out, "Autocollect status", json_object_new_string(l_val));
+                DAP_DELETE(l_val);
                 if (!l_status)
                     break;
                 s_print_autocollect_table(l_net, json_obj_out, "Fees");
@@ -1341,13 +1341,12 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
 
         case SUBCMD_UNDEFINED:
         default: {
-            char l_tmp_buff[70]={0};
             json_object* json_obj_out = json_object_new_object();
-            snprintf(l_tmp_buff, sizeof(l_tmp_buff), "Undefined block subcommand \"%s\" ",
-                                              l_subcmd_str);
-            json_object_object_add(json_obj_out, "status", json_object_new_string(l_tmp_buff));
+            char *l_val = dap_strdup_printf("Undefined block subcommand \"%s\" ", l_subcmd_str);
+            json_object_object_add(json_obj_out, "status", json_object_new_string(l_val));
+            DAP_DELETE(l_val);
             json_object_array_add(*json_arr_reply, json_obj_out);
-            ret=DAP_CHAIN_NODE_CLI_COM_BLOCK_UNKNOWN;
+            ret = DAP_CHAIN_NODE_CLI_COM_BLOCK_UNKNOWN;
 
         } break;
     }
diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c
index 261d64f99f8733f3853d5795658d2d4af39b3ed4..b8d6b9cddb7ded3eb9d4013a45bc17f05572fb6c 100644
--- a/modules/type/dag/dap_chain_cs_dag.c
+++ b/modules/type/dag/dap_chain_cs_dag.c
@@ -683,11 +683,7 @@ static bool s_chain_callback_datums_pool_proc(dap_chain_t *a_chain, dap_chain_da
      * or we have successfully chosen the hash(es) to link with.
      * No additional conditions required.
     */
-    byte_t *l_current_round_bytes = dap_global_db_get_sync(l_dag->gdb_group_events_round_new, DAG_ROUND_CURRENT_KEY, NULL, NULL, NULL);
-    uint64_t l_current_round = l_current_round_bytes ? *(uint64_t*)l_current_round_bytes : 0;
-    DAP_DEL_Z(l_current_round_bytes);
-    l_dag->round_completed = l_current_round++;
-    l_dag->round_current = l_current_round;
+    ++l_dag->round_id;
     uint64_t l_event_size = 0;
     dap_chain_cs_dag_event_t * l_event = l_dag->callback_cs_event_create
             ? l_dag->callback_cs_event_create(l_dag, a_datum, l_hashes, l_hashes_linked, &l_event_size)
@@ -708,18 +704,15 @@ static bool s_chain_callback_datums_pool_proc(dap_chain_t *a_chain, dap_chain_da
         } else
             return true;
     }
-
-    dap_global_db_set_sync(l_dag->gdb_group_events_round_new, DAG_ROUND_CURRENT_KEY,
-                      &l_current_round, sizeof(uint64_t), false);
     dap_chain_cs_dag_event_round_item_t l_round_item = { .round_info.datum_hash = l_datum_hash };
-    char *l_event_hash_hex_str = DAP_NEW_STACK_SIZE(char, DAP_CHAIN_HASH_FAST_STR_SIZE);
+    char l_event_hash_hex_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
     dap_chain_hash_fast_to_str(&l_event_hash, l_event_hash_hex_str, DAP_CHAIN_HASH_FAST_STR_SIZE);
     l_res = dap_chain_cs_dag_event_gdb_set(l_dag, l_event_hash_hex_str, l_event, l_event_size, &l_round_item);
     DAP_DELETE(l_event);
     log_it(l_res ? L_INFO : L_ERROR,
-           l_res ? "Event %s placed in the new forming round [id %"DAP_UINT64_FORMAT_U"]"
-                 : "Can't add new event [%s] to the new events round [id %"DAP_UINT64_FORMAT_U"]",
-           l_event_hash_hex_str, l_current_round);
+           l_res ? "Event %s placed into new forming round [id %"DAP_UINT64_FORMAT_U"]"
+                 : "Can't add new event %s to new events round [id %"DAP_UINT64_FORMAT_U"]",
+           l_event_hash_hex_str, l_dag->round_id);
     return l_res;
 }
 
@@ -1285,13 +1278,10 @@ static dap_chain_datum_t *s_chain_callback_datum_iter_get_next(dap_chain_datum_i
     return a_datum_iter->cur;
 }
 
-static bool s_json_dag_pack_round(json_object * a_json_out, dap_global_db_obj_t * a_objs, int i){
-    json_object * json_obj_event_i = json_object_new_object();
-    if (!strcmp(DAG_ROUND_CURRENT_KEY, a_objs[i].key)) {
-        json_object_object_add(json_obj_event_i, a_objs[i].key, json_object_new_uint64(*(uint64_t *)a_objs[i].value));
-        json_object_array_add(a_json_out, json_obj_event_i);
+static bool s_json_dag_pack_round(json_object * a_json_out, dap_global_db_obj_t * a_objs, int i) {
+    if ( !strcmp(DAG_ROUND_CURRENT_KEY, a_objs[i].key) )
         return true;
-    }
+    json_object * json_obj_event_i = json_object_new_object();
     dap_chain_cs_dag_event_t * l_event = (dap_chain_cs_dag_event_t *)
                     ((dap_chain_cs_dag_event_round_item_t *)a_objs[i].value)->event_n_signs;
     char buf[DAP_TIME_STR_SIZE];
diff --git a/modules/type/dag/dap_chain_cs_dag_event.c b/modules/type/dag/dap_chain_cs_dag_event.c
index 8e4fc060129010fbf0010edf8a07953441c6aec9..f89726a8330a77a48eb7ff8b83812c22ea743670 100644
--- a/modules/type/dag/dap_chain_cs_dag_event.c
+++ b/modules/type/dag/dap_chain_cs_dag_event.c
@@ -48,46 +48,38 @@ dap_chain_cs_dag_event_t *dap_chain_cs_dag_event_new(dap_chain_id_t a_chain_id,
                                                      dap_chain_hash_fast_t *a_hashes, size_t a_hashes_count, size_t *a_event_size)
 {
     assert(a_event_size);
-    size_t l_hashes_size = sizeof(*a_hashes)*a_hashes_count;
-    size_t l_datum_size =  dap_chain_datum_size(a_datum);
-    dap_chain_cs_dag_event_t * l_event_new = NULL;
-    size_t l_event_size = sizeof(l_event_new->header)
-            + l_hashes_size
-            + l_datum_size;
-    l_event_new = DAP_NEW_Z_SIZE(dap_chain_cs_dag_event_t, l_event_size);
-    l_event_new->header.ts_created = dap_time_now();
-    l_event_new->header.cell_id.uint64 = a_cell_id.uint64;
-    l_event_new->header.chain_id.uint64 = a_chain_id.uint64;
-    l_event_new->header.hash_count = a_hashes_count;
-    l_event_new->header.round_id = a_round_id;
-
-    if ( l_hashes_size ){
-        memcpy(l_event_new->hashes_n_datum_n_signs, a_hashes, l_hashes_size );
-    }
+    size_t l_hashes_size = sizeof(*a_hashes) * a_hashes_count,
+        l_datum_size = dap_chain_datum_size(a_datum),
+        l_event_size = sizeof(dap_chain_class_dag_event_hdr_t) + l_hashes_size + l_datum_size;
+    dap_chain_cs_dag_event_t *l_event_new = DAP_NEW_Z_SIZE(dap_chain_cs_dag_event_t, l_event_size);
+    *l_event_new = (dap_chain_cs_dag_event_t) {
+        { // .round_id = a_round_id,
+            .ts_created = dap_time_now(),
+            .chain_id = a_chain_id,
+            .cell_id = a_cell_id,
+            .hash_count = a_hashes_count
+        }
+    };
 
-    memcpy(l_event_new->hashes_n_datum_n_signs+l_hashes_size, a_datum,l_datum_size );
+    if ( l_hashes_size )
+        memcpy( l_event_new->hashes_n_datum_n_signs, a_hashes, l_hashes_size );
+    memcpy( l_event_new->hashes_n_datum_n_signs + l_hashes_size, a_datum,l_datum_size );
 
     if ( a_key ){
-        dap_sign_t * l_sign = dap_sign_create(a_key, l_event_new, l_event_size, 0);
-        if ( l_sign ){
-            size_t l_sign_size = dap_sign_get_size(l_sign);
-            l_event_size += l_sign_size;
-            l_event_new = (dap_chain_cs_dag_event_t *)DAP_REALLOC(l_event_new, l_event_size);
-            if (!l_event_new) {
-                log_it(L_CRITICAL, "Not enough memeory");
-                DAP_DELETE(l_sign);
-                return NULL;
-            }
-            memcpy(l_event_new->hashes_n_datum_n_signs + l_hashes_size + l_datum_size, l_sign, l_sign_size);
-            l_event_new->header.signs_count++;
-            log_it(L_INFO,"Created event size %zd, signed with sign size %zd", l_event_size, l_sign_size);
-            DAP_DELETE(l_sign);
-        }else {
-            log_it(L_ERROR,"Can't sign dag event!");
-            DAP_DELETE(l_event_new);
-            return NULL;
-        }
-    }else {
+        dap_sign_t *l_sign = dap_sign_create(a_key, l_event_new, l_event_size, 0);
+        if ( !l_sign )
+            return DAP_DELETE(l_event_new), log_it(L_ERROR,"Can't sign dag event!"), NULL;
+        size_t l_sign_size = dap_sign_get_size(l_sign);
+        l_event_size += l_sign_size;
+        dap_chain_cs_dag_event_t *l_event_newer = (dap_chain_cs_dag_event_t*)DAP_REALLOC(l_event_new, l_event_size);
+        if (!l_event_newer) 
+            return DAP_DEL_MULTY(l_event_new, l_sign), log_it(L_CRITICAL, "Not enough memeory"), NULL;
+        l_event_new = l_event_newer;
+        memcpy(l_event_new->hashes_n_datum_n_signs + l_hashes_size + l_datum_size, l_sign, l_sign_size);
+        l_event_new->header.signs_count++;
+        log_it(L_INFO,"Created event size %zd, signed with sign size %zd", l_event_size, l_sign_size);
+        DAP_DELETE(l_sign);
+    } else {
         log_it(L_NOTICE, "Created unsigned dag event");
     }
     if (a_event_size)
@@ -110,9 +102,7 @@ uint64_t dap_chain_cs_dag_event_calc_size_excl_signs(dap_chain_cs_dag_event_t *a
         return 0;
     dap_chain_datum_t *l_datum = (dap_chain_datum_t *)(a_event->hashes_n_datum_n_signs + l_hashes_size);
     uint64_t l_ret = dap_chain_datum_size(l_datum) + l_hashes_size + sizeof(a_event->header);
-    if (a_limit_size && a_limit_size < l_ret)
-        return 0;
-    return l_ret;
+    return a_limit_size && a_limit_size < l_ret ? 0 : l_ret;
 }
 
 /**
diff --git a/modules/type/dag/include/dap_chain_cs_dag.h b/modules/type/dag/include/dap_chain_cs_dag.h
index 1020634067194f1684b3fb16e7197d3690456880..42fc9e30ddd3f523e484e0626216b18493da7934 100644
--- a/modules/type/dag/include/dap_chain_cs_dag.h
+++ b/modules/type/dag/include/dap_chain_cs_dag.h
@@ -61,7 +61,7 @@ typedef struct dap_chain_cs_dag
     dap_chain_hash_fast_t static_genesis_event_hash;
     dap_chain_cs_dag_hal_item_t *hal;
 
-    atomic_uint_fast64_t round_current, round_completed;
+    atomic_uint_fast64_t round_id;
 
     uint16_t datum_add_hashes_count;
     char * gdb_group_events_round_new;