diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index a0f31fdb383784bce3e325ee8b2f0c31ab770ee6..ab659d337739a8be2e142fd3e4023b59d0fc4a0d 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -186,6 +186,7 @@ typedef struct dap_chain_net_pvt{
     struct block_reward *rewards;
     dap_chain_net_decree_t *decree;
     decree_table_t *decrees;
+    anchor_table_t *anchors;
 } dap_chain_net_pvt_t;
 
 typedef struct dap_chain_net_item{
@@ -3158,7 +3159,7 @@ int dap_chain_datum_add(dap_chain_t *a_chain, dap_chain_datum_t *a_datum, size_t
                 log_it(L_WARNING, "Corrupted anchor, datum size %zd is not equal to size of anchor %zd", l_datum_data_size, l_anchor_size);
                 return -102;
             }
-            return dap_chain_net_anchor_load(l_anchor, a_chain);
+            return dap_chain_net_anchor_load(l_anchor, a_chain, a_datum_hash);
         }
         case DAP_CHAIN_DATUM_TOKEN_DECL:
             return dap_ledger_token_load(l_ledger, a_datum->data, a_datum->header.data_size);
@@ -3205,32 +3206,22 @@ int dap_chain_datum_remove(dap_chain_t *a_chain, dap_chain_datum_t *a_datum, siz
     dap_ledger_t *l_ledger = dap_chain_net_by_id(a_chain->net_id)->pub.ledger;
     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;
-            size_t l_decree_size = dap_chain_datum_decree_get_size(l_decree);
-            if (l_decree_size != l_datum_data_size) {
-                log_it(L_WARNING, "Corrupted decree, datum size %zd is not equal to size of decree %zd", l_datum_data_size, l_decree_size);
-                return -102;
-            }*/
-            return 0; //dap_chain_net_decree_load(l_decree, a_chain, a_datum_hash);
+            return 0; 
         }
         case DAP_CHAIN_DATUM_ANCHOR: {
             dap_chain_datum_anchor_t *l_anchor = (dap_chain_datum_anchor_t *)a_datum->data;
-
-            
-
             size_t l_anchor_size = dap_chain_datum_anchor_get_size(l_anchor);
             if (l_anchor_size != l_datum_data_size) {
                 log_it(L_WARNING, "Corrupted anchor, datum size %zd is not equal to size of anchor %zd", l_datum_data_size, l_anchor_size);
                 return -102;
             }
-            return dap_chain_net_anchor_unload(l_anchor, a_chain);
+            return dap_chain_net_anchor_unload(l_anchor, a_chain, a_datum_hash);
         }
         case DAP_CHAIN_DATUM_TOKEN_DECL:
-            return 0;//dap_ledger_token_load(l_ledger, a_datum->data, a_datum->header.data_size);
+            return 0;
 
         case DAP_CHAIN_DATUM_TOKEN_EMISSION:
-            return 0;//dap_ledger_token_emission_load(l_ledger, a_datum->data, a_datum->header.data_size, a_datum_hash);
-
+            return 0;
         case DAP_CHAIN_DATUM_TX: {
             dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)a_datum->data;
             size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx);
@@ -3318,4 +3309,8 @@ void dap_chain_net_set_net_decree(dap_chain_net_t *a_net, dap_chain_net_decree_t
 
 decree_table_t **dap_chain_net_get_decrees(dap_chain_net_t *a_net) {
     return a_net ? &(PVT(a_net)->decrees) : NULL;
+}
+
+anchor_table_t **dap_chain_net_get_anchors(dap_chain_net_t *a_net) {
+    return a_net ? &(PVT(a_net)->anchors) : NULL;
 }
\ No newline at end of file
diff --git a/modules/net/dap_chain_net_anchor.c b/modules/net/dap_chain_net_anchor.c
index 2fab9b011989ffbf390aae33f44aa85aee285014..dde964b2d4481c500b626c1d207c35fb8059f107 100644
--- a/modules/net/dap_chain_net_anchor.c
+++ b/modules/net/dap_chain_net_anchor.c
@@ -40,6 +40,12 @@
 
 #define LOG_TAG "chain_net_anchor"
 
+typedef struct anchor_table{
+    dap_hash_fast_t anchor_hash;
+    dap_chain_datum_anchor_t *anchor;
+    UT_hash_handle hh;
+} anchor_table_t;  
+
 // private function prototypes
 static bool s_verify_pubkeys(dap_sign_t *a_sign, dap_sign_t **a_decree_signs, size_t a_num_of_decree_sign);
 static inline dap_sign_t *s_concate_all_signs_in_array(dap_sign_t *a_in_signs, size_t a_signs_size, size_t *a_sings_count, size_t *a_signs_arr_size);
@@ -134,7 +140,7 @@ int dap_chain_net_anchor_verify(dap_chain_net_t *a_net, dap_chain_datum_anchor_t
    return s_anchor_verify(a_net, a_anchor, a_data_size, false);
 }
 
-int dap_chain_net_anchor_load(dap_chain_datum_anchor_t * a_anchor, dap_chain_t *a_chain)
+int dap_chain_net_anchor_load(dap_chain_datum_anchor_t * a_anchor, dap_chain_t *a_chain, dap_hash_fast_t *a_anchor_hash)
 {
     int ret_val = 0;
 
@@ -165,90 +171,106 @@ 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)) != 0){
         log_it(L_WARNING, "Decree applying failed");
+        return ret_val;
+    }
+        
+
+    anchor_table_t **l_anchors = dap_chain_net_get_anchors(l_net);
+    anchor_table_t *l_new_anchor = DAP_NEW_Z(anchor_table_t);
+    l_new_anchor->anchor_hash = *a_anchor_hash;
+    l_new_anchor->anchor = a_anchor;
+    HASH_ADD(hh, *l_anchors, anchor_hash, sizeof(l_new_anchor->anchor_hash), l_new_anchor);
 
     return ret_val;
 }
 
-dap_chain_datum_anchor_t * s_find_previous_anchor(dap_chain_datum_anchor_t * a_anchor, dap_chain_t *a_chain)
+dap_chain_datum_anchor_t * s_find_previous_anchor(dap_hash_fast_t *a_old_anchor_hash, dap_chain_net_t *a_net)
 {
-    if (!a_anchor || !a_chain){
+    if (!a_old_anchor_hash || !a_net){
         log_it(L_ERROR,"Params are NULL");
         return NULL;
     }
-    dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id);
+    
+    dap_chain_net_t *l_net = a_net;
     dap_chain_datum_anchor_t * l_ret_anchor = NULL;
+    dap_chain_datum_anchor_t *l_old_anchor = NULL;
+
+    anchor_table_t **l_anchors_ptr = dap_chain_net_get_anchors(l_net);
+    anchor_table_t *l_anchor = NULL;
+    HASH_FIND(hh, *l_anchors_ptr, a_old_anchor_hash, sizeof(*a_old_anchor_hash), l_anchor);
+    if (!l_old_anchor){
+        log_it(L_WARNING,"Can not find anchor");
+        return NULL;
+    }
+
+    l_old_anchor = l_anchor->anchor;
 
     dap_hash_fast_t l_old_decrere_hash = {};
-    if (dap_chain_datum_anchor_get_hash_from_data(a_anchor, &l_old_decrere_hash) != 0)
+    if (dap_chain_datum_anchor_get_hash_from_data(l_old_anchor, &l_old_decrere_hash) != 0)
         return NULL;
     dap_chain_datum_decree_t *l_old_decree = dap_chain_net_decree_get_by_hash(l_net, &l_old_decrere_hash, NULL);
     uint16_t l_old_decree_type = l_old_decree->header.type;
     uint16_t l_old_decree_subtype = l_old_decree->header.sub_type;
 
-    dap_chain_cell_t *l_cell = a_chain->cells;
-    size_t l_atom_size = 0;
-    dap_chain_atom_iter_t *l_atom_iter = a_chain->callback_atom_iter_create(a_chain, l_cell->id, 0);
-    dap_chain_atom_ptr_t l_atom = a_chain->callback_atom_iter_get(l_atom_iter, DAP_CHAIN_ITER_OP_LAST, &l_atom_size);
-    while(l_atom && l_atom_size){
+    anchor_table_t *l_anchors = HASH_LAST(*l_anchors_ptr);
+    for(; l_anchors; l_anchors = l_anchors->hh.prev){
         size_t l_datums_count = 0;
-        dap_chain_datum_t **l_datums = a_chain->callback_atom_get_datums(l_atom, l_atom_size, &l_datums_count);
-        dap_chain_datum_t *l_datum, *l_datum2;
-        for(size_t l_datum_n = 0; l_datum_n < l_datums_count; l_datum_n++) {
-            if ( ! (l_datum = l_datums[l_datum_n]) )
-                continue;
-
-            if (l_datum->header.type_id != DAP_CHAIN_DATUM_ANCHOR || a_anchor == (dap_chain_datum_anchor_t *)l_datum->data)
-                continue;
 
-            dap_chain_datum_anchor_t *l_curr_anchor = (dap_chain_datum_anchor_t *)l_datum->data;
-            dap_hash_fast_t l_hash = {};
-            if (dap_chain_datum_anchor_get_hash_from_data(l_curr_anchor, &l_hash) != 0)
-                continue;
+        dap_chain_datum_anchor_t *l_curr_anchor = l_anchors->anchor;
+        dap_hash_fast_t l_hash = {};
+        if (dap_chain_datum_anchor_get_hash_from_data(l_curr_anchor, &l_hash) != 0)
+            continue;
+        
+        bool l_is_applied = false;
+        dap_chain_datum_decree_t *l_decree = dap_chain_net_decree_get_by_hash(l_net, &l_hash, &l_is_applied);
+        if (!l_decree)
+            continue;
+
+        if (l_decree->header.type == l_old_decree_type && l_old_decree_type == DAP_CHAIN_DATUM_DECREE_TYPE_COMMON && 
+            l_old_decree_subtype == DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_INVALIDATE &&
+            l_decree->header.sub_type == DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_APPROVE){
             
-            bool l_is_applied = false;
-            dap_chain_datum_decree_t *l_decree = dap_chain_net_decree_get_by_hash(l_net, &l_hash, &l_is_applied);
-            if (!l_decree)
+            dap_chain_addr_t l_addr_old, l_addr_new = {};
+            if (dap_chain_datum_decree_get_stake_signing_addr(l_old_decree, &l_addr_old)){
                 continue;
+            }
 
-            if (l_decree->header.type == l_old_decree_type && l_old_decree_type == DAP_CHAIN_DATUM_DECREE_TYPE_COMMON && 
-                l_old_decree_subtype == DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_INVALIDATE &&
-                l_decree->header.sub_type == DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_APPROVE){
-                
-                dap_chain_addr_t l_addr_old, l_addr_new = {};
-                if (dap_chain_datum_decree_get_stake_signing_addr(l_old_decree, &l_addr_old)){
-                    continue;
-                }
-
-                if (dap_chain_datum_decree_get_stake_signing_addr(l_decree, &l_addr_new)){
-                    continue;
-                }
+            if (dap_chain_datum_decree_get_stake_signing_addr(l_decree, &l_addr_new)){
+                continue;
+            }
 
-                if(dap_chain_addr_compare(&l_addr_old, &l_addr_new)){
-                    l_ret_anchor = l_curr_anchor;
-                    dap_chain_net_decree_reset_applied(l_net, &l_hash);
-                break;
-                }
-            } else if (l_decree->header.type == l_old_decree_type && l_decree->header.sub_type == l_old_decree_subtype){
-                // check addr if l_decree type is stake approve
+            if(dap_chain_addr_compare(&l_addr_old, &l_addr_new)){
                 l_ret_anchor = l_curr_anchor;
                 dap_chain_net_decree_reset_applied(l_net, &l_hash);
-                break;
+            break;
             }
+        } else if (l_decree->header.type == l_old_decree_type && l_decree->header.sub_type == l_old_decree_subtype){
+            // check addr if l_decree type is stake approve
+            l_ret_anchor = l_curr_anchor;
+            dap_chain_net_decree_reset_applied(l_net, &l_hash);
+            break;
         }
-        DAP_DEL_Z(l_datums);
         if (l_ret_anchor)
             break;
-        // go to previous atom
-        l_atom = a_chain->callback_atom_iter_get(l_atom_iter, DAP_CHAIN_ITER_OP_PREV, &l_atom_size);
     }
-    a_chain->callback_atom_iter_delete(l_atom_iter);
 
     return l_ret_anchor;
 }
 
-int dap_chain_net_anchor_unload(dap_chain_datum_anchor_t * a_anchor, dap_chain_t *a_chain)
+void s_delete_anchor(dap_chain_net_t *a_net, dap_hash_fast_t *a_anchor_hash)
+{
+    anchor_table_t **l_anchors_ptr = dap_chain_net_get_anchors(a_net);
+    anchor_table_t *l_anchor = NULL;
+    HASH_FIND(hh, *l_anchors_ptr, a_anchor_hash, sizeof(*a_anchor_hash), l_anchor);
+    if(l_anchor){
+        HASH_DEL(*l_anchors_ptr, l_anchor);
+        DAP_DEL_Z(l_anchor);
+    }
+}
+
+int dap_chain_net_anchor_unload(dap_chain_datum_anchor_t * a_anchor, dap_chain_t *a_chain, dap_hash_fast_t *a_anchor_hash)
 {
     int ret_val = 0;
 
@@ -287,7 +309,8 @@ int dap_chain_net_anchor_unload(dap_chain_datum_anchor_t * a_anchor, dap_chain_t
         {
             case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_FEE:{
                 dap_chain_net_decree_reset_applied(l_net, &l_hash);
-                dap_chain_datum_anchor_t * l_new_anchor = s_find_previous_anchor(a_anchor, a_chain);
+                dap_chain_datum_anchor_t * l_new_anchor = s_find_previous_anchor(a_anchor_hash, l_net);
+                s_delete_anchor(l_net, a_anchor_hash);
                 if (l_new_anchor){// if previous anchor is founded apply it
                     dap_chain_hash_fast_t l_hash = {0};
                     if ((ret_val = dap_chain_datum_anchor_get_hash_from_data(l_new_anchor, &l_hash)) != 0){
@@ -317,12 +340,14 @@ int dap_chain_net_anchor_unload(dap_chain_datum_anchor_t * a_anchor, dap_chain_t
                 }
                 dap_chain_net_srv_stake_key_invalidate(&l_signing_addr);
                 dap_chain_net_decree_reset_applied(l_net, &l_hash);
+                s_delete_anchor(l_net, a_anchor_hash);
             }
             break;
             case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_INVALIDATE:{
                 // Find previous anchor with this stake approve and apply it 
                 dap_chain_net_decree_reset_applied(l_net, &l_hash);
                 dap_chain_datum_anchor_t * l_new_anchor = s_find_previous_anchor(a_anchor, a_chain);
+                s_delete_anchor(l_net, a_anchor_hash);
                 if (l_new_anchor){// if previous anchor is founded apply it
                     dap_chain_hash_fast_t l_hash = {0};
                     if ((ret_val = dap_chain_datum_anchor_get_hash_from_data(l_new_anchor, &l_hash)) != 0){
@@ -339,6 +364,7 @@ int dap_chain_net_anchor_unload(dap_chain_datum_anchor_t * a_anchor, dap_chain_t
             case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALUE:{
                 dap_chain_net_decree_reset_applied(l_net, &l_hash);
                 dap_chain_datum_anchor_t * l_new_anchor = s_find_previous_anchor(a_anchor, a_chain);
+                s_delete_anchor(l_net, a_anchor_hash);
                 if (l_new_anchor){// if previous anchor is founded apply it
                     dap_chain_hash_fast_t l_hash = {0};
                     if ((ret_val = dap_chain_datum_anchor_get_hash_from_data(l_new_anchor, &l_hash)) != 0){
@@ -358,6 +384,7 @@ int dap_chain_net_anchor_unload(dap_chain_datum_anchor_t * a_anchor, dap_chain_t
             case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALIDATORS_COUNT:{
                 dap_chain_net_decree_reset_applied(l_net, &l_hash);
                 dap_chain_datum_anchor_t * l_new_anchor = s_find_previous_anchor(a_anchor, a_chain);
+                s_delete_anchor(l_net, a_anchor_hash);
                 if (l_new_anchor){// if previous anchor is founded apply it
                     dap_chain_hash_fast_t l_hash = {0};
                     if ((ret_val = dap_chain_datum_anchor_get_hash_from_data(l_new_anchor, &l_hash)) != 0){
@@ -378,6 +405,7 @@ int dap_chain_net_anchor_unload(dap_chain_datum_anchor_t * a_anchor, dap_chain_t
                 // find previous anchor with rewarrd and apply it
                 dap_chain_net_decree_reset_applied(l_net, &l_hash);
                 dap_chain_net_remove_last_reward(dap_chain_net_by_id(a_chain->net_id));
+                s_delete_anchor(l_net, a_anchor_hash);
             }
             break;
             case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_OWNERS:
diff --git a/modules/net/dap_chain_net_decree.c b/modules/net/dap_chain_net_decree.c
index 9433256eb788451facee26a448f68c9b9409c27d..46d6c126472ff3e5c110872b348a772d2e4116d5 100644
--- a/modules/net/dap_chain_net_decree.c
+++ b/modules/net/dap_chain_net_decree.c
@@ -245,7 +245,6 @@ int dap_chain_net_decree_apply(dap_hash_fast_t *a_decree_hash, dap_chain_datum_d
 
     decree_table_t **l_decrees = dap_chain_net_get_decrees(l_net), *l_new_decree;
     HASH_FIND(hh, *l_decrees, a_decree_hash, sizeof(dap_hash_fast_t), l_new_decree);
-
     if (!l_new_decree) {
         l_new_decree = DAP_NEW_Z(decree_table_t);
         if (!l_new_decree) {
diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h
index 6e9f139a5223f361a849eda5c49a5c7c1f25c485..6e62d461f70fb3948bcfad59038a16bd2368dedb 100644
--- a/modules/net/include/dap_chain_net.h
+++ b/modules/net/include/dap_chain_net.h
@@ -44,6 +44,7 @@ typedef struct dap_chain_node_client dap_chain_node_client_t;
 typedef struct dap_ledger dap_ledger_t;
 typedef struct dap_chain_net_decree dap_chain_net_decree_t;
 typedef struct decree_table decree_table_t;
+typedef struct anchor_table anchor_table_t;
 typedef enum dap_chain_net_state {
     NET_STATE_OFFLINE = 0,
     NET_STATE_LINKS_PREPARE,
@@ -233,4 +234,5 @@ enum dap_chain_net_json_rpc_error_list{
 };
 dap_chain_net_decree_t *dap_chain_net_get_net_decree(dap_chain_net_t *a_net);
 void dap_chain_net_set_net_decree(dap_chain_net_t *a_net, dap_chain_net_decree_t *a_decree);
-decree_table_t **dap_chain_net_get_decrees(dap_chain_net_t *a_net);
\ No newline at end of file
+decree_table_t **dap_chain_net_get_decrees(dap_chain_net_t *a_net);
+anchor_table_t **dap_chain_net_get_anchors(dap_chain_net_t *a_net);
\ No newline at end of file
diff --git a/modules/net/include/dap_chain_net_anchor.h b/modules/net/include/dap_chain_net_anchor.h
index 1a44cab2a1f10439cd03d4c91b355c78d3380355..7275e2c2b3ca0e4143c30f692de3f471b72a9dc4 100644
--- a/modules/net/include/dap_chain_net_anchor.h
+++ b/modules/net/include/dap_chain_net_anchor.h
@@ -24,6 +24,8 @@
 #include "dap_chain_datum_anchor.h"
 #include "dap_chain_net.h"
 
+int dap_chain_net_anchor_init(dap_chain_net_t *a_net);
+
 int dap_chain_net_anchor_verify(dap_chain_net_t *a_net, dap_chain_datum_anchor_t * a_anchor, size_t a_data_size);
-int dap_chain_net_anchor_load(dap_chain_datum_anchor_t * a_anchor, dap_chain_t *a_chain);
-int dap_chain_net_anchor_unload(dap_chain_datum_anchor_t * a_anchor, dap_chain_t *a_chain);
\ No newline at end of file
+int dap_chain_net_anchor_load(dap_chain_datum_anchor_t * a_anchor, dap_chain_t *a_chain, dap_hash_fast_t *a_anchor_hash);
+int dap_chain_net_anchor_unload(dap_chain_datum_anchor_t * a_anchor, dap_chain_t *a_chain, dap_hash_fast_t *a_anchor_hash);
\ No newline at end of file
diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c
index 01a2468ff55625627c71735f8a5129ec0dd21d83..66041b7d628e1ded6b362070e01e0f537e599927 100644
--- a/modules/type/blocks/dap_chain_cs_blocks.c
+++ b/modules/type/blocks/dap_chain_cs_blocks.c
@@ -62,10 +62,12 @@ typedef struct dap_chain_cs_blocks_pvt
 
     size_t forked_br_cnt;
     dap_chain_block_forked_branch_t **forked_branches; // list of lists with atoms in side branches
+    pthread_rwlock_t forked_branches_rwlock;
 
     // Chunks treshold
     dap_chain_block_chunks_t * chunks;
     dap_chain_block_datum_index_t *datum_index; // To find datum in blocks
+    pthread_rwlock_t datums_rwlock;
 
     dap_chain_hash_fast_t genesis_block_hash;
     dap_chain_hash_fast_t static_genesis_block_hash;
@@ -78,12 +80,24 @@ typedef struct dap_chain_cs_blocks_pvt
     dap_timerfd_t *fill_timer;
     uint64_t fill_timeout;
 
-    pthread_rwlock_t rwlock, datums_rwlock;
+    pthread_rwlock_t rwlock;
     struct cs_blocks_hal_item *hal;
 } dap_chain_cs_blocks_pvt_t;
 
 #define PVT(a) ((dap_chain_cs_blocks_pvt_t *)(a)->_pvt )
 
+#define print_rdlock(blocks) log_it(L_DEBUG, "Try to rdlock, %s, %d, thread_id=%u", __FUNCTION__, __LINE__, dap_gettid());\
+        pthread_rwlock_rdlock(& PVT(blocks)->rwlock);\
+        log_it(L_DEBUG, "Locked rdlock, %s, %d, thread_id=%u", __FUNCTION__, __LINE__, dap_gettid());
+
+#define print_wrlock(blocks) log_it(L_DEBUG, "Try to wrlock, %s, %d, thread_id=%u", __FUNCTION__, __LINE__, dap_gettid());\
+        pthread_rwlock_wrlock(& PVT(blocks)->rwlock);\
+        log_it(L_DEBUG, "Locked wrlock, %s, %d, thread_id=%u", __FUNCTION__, __LINE__, dap_gettid());
+
+#define print_unlock(blocks) log_it(L_DEBUG, "Try to unlock, %s, %d, thread_id=%u", __FUNCTION__, __LINE__, dap_gettid());\
+        pthread_rwlock_unlock(& PVT(blocks)->rwlock);\
+        log_it(L_DEBUG, "Unlocked rwqlock, %s, %d, thread_id=%u", __FUNCTION__, __LINE__, dap_gettid());
+
 static int s_cli_parse_cmd_hash(char ** a_argv, int a_arg_index, int a_argc, void **a_str_reply,const char * a_param, dap_chain_hash_fast_t * a_datum_hash);
 static void s_cli_meta_hash_print(  json_object* json_obj_a, const char * a_meta_title, dap_chain_block_meta_t * a_meta);
 static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply);
@@ -155,7 +169,7 @@ int dap_chain_cs_blocks_init()
 {
     dap_chain_cs_type_add("blocks", s_chain_cs_blocks_new);
     s_seed_mode = dap_config_get_item_bool_default(g_config,"general","seed_mode",false);
-    s_debug_more = true; //dap_config_get_item_bool_default(g_config, "blocks", "debug_more", false);
+    s_debug_more = dap_config_get_item_bool_default(g_config, "blocks", "debug_more", false);
     dap_cli_server_cmd_add ("block", s_cli_blocks, "Create and explore blockchains",
         "New block create, fill and complete commands:\n"
             "block -net <net_name> -chain <chain_name> new\n"
@@ -286,6 +300,7 @@ static int s_chain_cs_blocks_new(dap_chain_t *a_chain, dap_config_t *a_chain_con
     l_cs_blocks->_pvt = l_cs_blocks_pvt;
     pthread_rwlock_init(&l_cs_blocks_pvt->rwlock,NULL);
     pthread_rwlock_init(&l_cs_blocks_pvt->datums_rwlock, NULL);
+    pthread_rwlock_init(&l_cs_blocks_pvt->forked_branches_rwlock, NULL);
 
     const char * l_genesis_blocks_hash_str = dap_config_get_item_str_default(a_chain_config,"blocks","genesis_block",NULL);
     if ( l_genesis_blocks_hash_str ){
@@ -1339,6 +1354,7 @@ static void s_callback_delete(dap_chain_t * a_chain)
     pthread_rwlock_unlock(&PVT(l_blocks)->rwlock);
     pthread_rwlock_destroy(&PVT(l_blocks)->rwlock);
     pthread_rwlock_destroy(&PVT(l_blocks)->datums_rwlock);
+    pthread_rwlock_destroy(&PVT(l_blocks)->forked_branches_rwlock);
     dap_chain_block_chunks_delete(PVT(l_blocks)->chunks);
     DAP_DEL_Z(l_blocks->_inheritor);
     DAP_DEL_Z(l_blocks->_pvt);
@@ -1348,6 +1364,19 @@ static void s_callback_delete(dap_chain_t * a_chain)
 static void s_callback_cs_blocks_purge(dap_chain_t *a_chain)
 {
     dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain);
+
+    pthread_rwlock_wrlock(&PVT(l_blocks)->forked_branches_rwlock);
+    for (size_t i = 0; i < PVT(l_blocks)->forked_br_cnt; i++){
+        dap_chain_block_forked_branch_atoms_table_t *l_atom_tmp, *l_atom;
+        HASH_ITER(hh, PVT(l_blocks)->forked_branches[i]->forked_branch_atoms, l_atom, l_atom_tmp) {
+            HASH_DEL(PVT(l_blocks)->forked_branches[i]->forked_branch_atoms, l_atom);
+            l_atom = NULL;
+        }
+        DAP_DEL_Z(PVT(l_blocks)->forked_branches[i]);
+    }
+    DAP_DEL_Z(PVT(l_blocks)->forked_branches);
+    pthread_rwlock_unlock(&PVT(l_blocks)->forked_branches_rwlock);
+
     pthread_rwlock_wrlock(&PVT(l_blocks)->rwlock);
     dap_chain_block_cache_t *l_block = NULL, *l_block_tmp = NULL;
     HASH_ITER(hh, PVT(l_blocks)->blocks, l_block, l_block_tmp) {
@@ -1467,73 +1496,6 @@ static void s_add_atom_to_blocks(dap_chain_cs_blocks_t *a_blocks, dap_chain_bloc
 }
 
 
-/**
- * @brief s_bft_consensus_setup
- * @param a_blocks
- */
-static void s_bft_consensus_setup(dap_chain_cs_blocks_t * a_blocks)
-{
-    bool l_was_chunks_changed = false;
-    // Compare all chunks with chain's tail
-    for (dap_chain_block_chunk_t *l_chunk = PVT(a_blocks)->chunks->chunks_last ; l_chunk; l_chunk=l_chunk->prev ){
-        size_t l_chunk_length = HASH_COUNT(l_chunk->block_cache_hash);
-        dap_chain_block_cache_t * l_block_cache_chunk_top_prev = dap_chain_block_cache_get_by_hash(a_blocks,&l_chunk->block_cache_top->prev_hash);
-        dap_chain_block_cache_t * l_block_cache= l_block_cache_chunk_top_prev;
-        if ( l_block_cache ){ // we found prev block in main chain
-            size_t l_tail_length = 0;
-            // Now lets calc tail length
-            for( ;l_block_cache; l_block_cache=l_block_cache->prev){
-                l_tail_length++;
-                if(l_tail_length>l_chunk_length)
-                    break;
-            }
-            if(l_tail_length<l_chunk_length ){ // This generals consensus is bigger than the current one
-                // Cutoff current chank from the list
-                if( l_chunk->next)
-                    l_chunk->next->prev = l_chunk->prev;
-                if( l_chunk->prev)
-                    l_chunk->prev->next = l_chunk->next;
-
-                // Pass through all the tail and move it to chunks
-                for(l_block_cache= l_block_cache_chunk_top_prev ;l_block_cache; l_block_cache=l_block_cache->prev){
-                    pthread_rwlock_wrlock(& PVT(a_blocks)->rwlock);
-                    if(l_block_cache->prev)
-                        l_block_cache->prev->next = l_block_cache->next;
-                    if(l_block_cache->next)
-                        l_block_cache->next->prev = l_block_cache->prev;
-                    HASH_DEL(PVT(a_blocks)->blocks,l_block_cache);
-                    --PVT(a_blocks)->blocks_count;
-                    pthread_rwlock_unlock(& PVT(a_blocks)->rwlock);
-                    dap_chain_block_chunks_add(PVT(a_blocks)->chunks,l_block_cache);
-                }
-                // Pass through all the chunk and add it to main chain
-                for(l_block_cache= l_chunk->block_cache_top ;l_block_cache; l_block_cache=l_block_cache->prev){
-                    int l_check_res = 0;
-                    if (a_blocks->callback_block_verify)
-                        l_check_res = a_blocks->callback_block_verify(a_blocks, l_block_cache->block, l_block_cache->block_size);
-                    if (!l_check_res) {
-                        log_it(L_WARNING,"Can't move block %s from chunk to main chain - data inside wasn't verified: code %d",
-                                            l_block_cache->block_hash_str, l_check_res);
-                        dap_chain_block_chunks_add(PVT(a_blocks)->chunks,l_block_cache);
-                    }
-                    // TODO Rework blocks rwlock usage for this code
-                    HASH_ADD(hh, PVT(a_blocks)->blocks, block_hash, sizeof(l_block_cache->block_hash), l_block_cache);
-                    ++PVT(a_blocks)->blocks_count;
-                    s_add_atom_datums(a_blocks, l_block_cache);
-                }
-                dap_chain_block_chunk_delete(l_chunk );
-                l_was_chunks_changed = true;
-            }
-        }
-
-    }
-    if(l_was_chunks_changed){
-        dap_chain_block_chunks_sort( PVT(a_blocks)->chunks);
-        log_it(L_INFO,"Recursive BFT stage additional check...");
-        s_bft_consensus_setup(a_blocks);
-    }
-}
-
 static void s_select_longest_branch(dap_chain_cs_blocks_t * a_blocks, dap_chain_block_cache_t * a_bcache, uint64_t a_main_branch_length, dap_chain_cell_t *a_cell)
 {
     dap_chain_cs_blocks_t * l_blocks = a_blocks;