diff --git a/modules/chain/dap_chain_ch.c b/modules/chain/dap_chain_ch.c
index 2408af9abd05bc29689d681c52ce0cc5aef608da..344e252e3859b870250a42430c332dddda522b6d 100644
--- a/modules/chain/dap_chain_ch.c
+++ b/modules/chain/dap_chain_ch.c
@@ -645,6 +645,7 @@ static bool s_sync_in_chains_callback(void *a_arg)
     }
     case ATOM_FORK: {
         debug_if(s_debug_more, L_WARNING, "Atom with hash %s for %s:%s added to a fork branch.", l_atom_hash_str, l_chain->net_name, l_chain->name);
+        l_ack_send = true;
         break;
     }
     default:
diff --git a/modules/consensus/esbocs/dap_chain_cs_esbocs.c b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
index 4f2d2489069bc7722c9f5d47a45f04be7ce066de..41b5a23e711768a6f353558b87e475f6748fdca0 100644
--- a/modules/consensus/esbocs/dap_chain_cs_esbocs.c
+++ b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
@@ -78,7 +78,7 @@ static int s_callback_new(dap_chain_t *a_chain, dap_config_t *a_chain_cfg);
 static void s_callback_delete(dap_chain_cs_blocks_t *a_blocks);
 static int s_callback_created(dap_chain_t *a_chain, dap_config_t *a_chain_net_cfg);
 static size_t s_callback_block_sign(dap_chain_cs_blocks_t *a_blocks, dap_chain_block_t **a_block_ptr, size_t a_block_size);
-static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_block_t *a_block, size_t a_block_size);
+static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_block_t *a_block, dap_hash_fast_t *a_block_hash, size_t a_block_size);
 static void s_db_change_notifier(dap_store_obj_t *a_obj, void * a_arg);
 static dap_list_t *s_check_emergency_rights(dap_chain_esbocs_t *a_esbocs, dap_chain_addr_t *a_signing_addr);
 static int s_cli_esbocs(int a_argc, char **a_argv, void **a_str_reply);
@@ -2783,42 +2783,29 @@ static uint64_t s_get_precached_key_hash(struct precached_key **a_precached_keys
     return 0;
 }
 
-static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_block_t *a_block, size_t a_block_size)
+static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_block_t *a_block, dap_hash_fast_t *a_block_hash, size_t a_block_size)
 {
     dap_chain_esbocs_t *l_esbocs = DAP_CHAIN_ESBOCS(a_blocks);
     dap_chain_esbocs_pvt_t *l_esbocs_pvt = PVT(l_esbocs);
 
-    if (sizeof(a_block->hdr) >= a_block_size) {
-        log_it(L_WARNING, "Incorrect header size with block %p on chain %s", a_block, a_blocks->chain->name);
-        return  -7;
-    }
-    size_t l_offset = dap_chain_block_get_sign_offset(a_block, a_block_size);
-    if (!l_offset) {
-        log_it(L_WARNING, "Block with size %zu parsing error", a_block_size);
-        return -5;
-    }
-    if ((a_block->hdr.meta_n_datum_n_signs_size > l_offset || a_block->hdr.version == 2) &&
-            a_block->hdr.meta_n_datum_n_signs_size != a_block_size - sizeof(a_block->hdr)) {
-        log_it(L_WARNING, "Incorrect size with block %p on chain %s", a_block, a_blocks->chain->name);
-        return -8;
-    }
-
     if (l_esbocs->session && l_esbocs->session->processing_candidate == a_block)
         // It's a block candidate, don't check signs
-        return 0;
-
+        return a_block->hdr.version > 1 ? 0 : -3;
 
+    size_t l_block_size = a_block_size; // /* Can't calc it for many old bugged blocks */ dap_chain_block_get_size(a_block);
     size_t l_signs_count = 0;
+    size_t l_offset = dap_chain_block_get_sign_offset(a_block, l_block_size);
     dap_sign_t **l_signs = dap_sign_get_unique_signs(a_block->meta_n_datum_n_sign+l_offset,
-                                            a_block_size-sizeof(a_block->hdr)-l_offset, &l_signs_count);
+                                            l_block_size-sizeof(a_block->hdr)-l_offset, &l_signs_count);
     if (!l_signs_count){
-        log_it(L_ERROR, "No any signatures at all for block");
+        log_it(L_ERROR, "No any signatures at all for block %s", dap_hash_fast_to_str_static(a_block_hash));
         DAP_DELETE(l_signs);
         return -2;
     }
 
     if (l_signs_count < l_esbocs_pvt->min_validators_count) {
-        log_it(L_ERROR, "Corrupted block: not enough signs: %zu of %hu", l_signs_count, l_esbocs_pvt->min_validators_count);
+        log_it(L_ERROR, "Corrupted block  %s: not enough signs: %zu of %hu", dap_hash_fast_to_str_static(a_block_hash),
+                                    l_signs_count, l_esbocs_pvt->min_validators_count);
         DAP_DELETE(l_signs);
         return -1;
     }
@@ -2826,60 +2813,73 @@ static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_bl
     // Parse the rest signs
     int l_ret = 0;
     uint16_t l_signs_verified_count = 0;
-    size_t l_block_excl_sign_size = dap_chain_block_get_sign_offset(a_block, a_block_size) + sizeof(a_block->hdr);
-    bool l_block_is_emergency = s_block_is_emergency(a_block, a_block_size);
+    size_t l_block_excl_sign_size = dap_chain_block_get_sign_offset(a_block, l_block_size) + sizeof(a_block->hdr);
+    bool l_block_is_emergency = s_block_is_emergency(a_block, l_block_size);
     // Get the header on signing operation time
     size_t l_block_original = a_block->hdr.meta_n_datum_n_signs_size;
     a_block->hdr.meta_n_datum_n_signs_size = l_block_excl_sign_size - sizeof(a_block->hdr);
     for (size_t i = 0; i < l_signs_count; i++) {
         dap_sign_t *l_sign = l_signs[i];
-        if (!dap_sign_verify_size(l_sign, a_block_size - l_block_excl_sign_size + sizeof(a_block->hdr))) {
-            log_it(L_ERROR, "Corrupted block: sign size is bigger than block size");
-            l_ret = -3;
-            break;
-        }
         dap_chain_addr_t l_signing_addr = { .net_id = a_blocks->chain->net_id };
         s_get_precached_key_hash(&l_esbocs_pvt->precached_keys, l_sign, &l_signing_addr.data.hash_fast);
         if (!l_esbocs_pvt->poa_mode) {
              // Compare signature with delegated keys
             if (!dap_chain_net_srv_stake_key_delegated(&l_signing_addr)) {
-                debug_if(l_esbocs_pvt->debug, L_ATT, "Unknown PoS signer %s",
-                    dap_chain_hash_fast_to_str_static(&l_signing_addr.data.hash_fast));
+                if (l_esbocs_pvt->debug) {
+                    char l_block_hash_str[DAP_HASH_FAST_STR_SIZE];
+                    dap_hash_fast_to_str(a_block_hash, l_block_hash_str, DAP_HASH_FAST_STR_SIZE);
+                    log_it(L_ATT, "Unknown PoS signer %s for block %s", dap_hash_fast_to_str_static(&l_signing_addr.data.hash_fast), l_block_hash_str);
+                }
                 continue;
             }
         } else {
             // Compare signature with auth_certs
             if (!s_validator_check(&l_signing_addr, l_esbocs_pvt->poa_validators)) {
-                debug_if(l_esbocs_pvt->debug, L_ATT, "Unknown PoA signer %s",
-                    dap_chain_hash_fast_to_str_static(&l_signing_addr.data.hash_fast));
+                if (l_esbocs_pvt->debug) {
+                    char l_block_hash_str[DAP_HASH_FAST_STR_SIZE];
+                    dap_hash_fast_to_str(a_block_hash, l_block_hash_str, DAP_HASH_FAST_STR_SIZE);
+                    log_it(L_ATT, "Unknown PoA signer %s for block %s", dap_hash_fast_to_str_static(&l_signing_addr.data.hash_fast), l_block_hash_str);
+                }
                 continue;
             }
         }
         if (i == 0) {
             if (l_block_is_emergency && !s_check_emergency_rights(l_esbocs, &l_signing_addr)) {
-                log_it(L_ATT, "Restricted emergency block submitter %s",
-                                dap_chain_hash_fast_to_str_static(&l_signing_addr.data.hash_fast));
+                if (l_esbocs_pvt->debug) {
+                    char l_block_hash_str[DAP_HASH_FAST_STR_SIZE];
+                    dap_hash_fast_to_str(a_block_hash, l_block_hash_str, DAP_HASH_FAST_STR_SIZE);
+                    log_it(L_ATT, "Restricted emergency block submitter %s for block %s", dap_hash_fast_to_str_static(&l_signing_addr.data.hash_fast), l_block_hash_str);
+                }
                 l_ret = -5;
                 break;
             } else if (l_esbocs_pvt->check_signs_structure &&
-                       !s_check_signing_rights(l_esbocs, a_block, a_block_size, &l_signing_addr, true)) {
-                log_it(L_ATT, "Restricted block submitter %s",
-                                dap_chain_hash_fast_to_str_static(&l_signing_addr.data.hash_fast));
+                       !s_check_signing_rights(l_esbocs, a_block, l_block_size, &l_signing_addr, true)) {
+                if (l_esbocs_pvt->debug) {
+                    char l_block_hash_str[DAP_HASH_FAST_STR_SIZE];
+                    dap_hash_fast_to_str(a_block_hash, l_block_hash_str, DAP_HASH_FAST_STR_SIZE);
+                    log_it(L_ATT, "Restricted block submitter %s for block %s", dap_hash_fast_to_str_static(&l_signing_addr.data.hash_fast), l_block_hash_str);
+                }
                 l_ret = -5;
                 break;
             }
         } else {
             if (l_block_is_emergency && !s_check_emergency_rights(l_esbocs, &l_signing_addr) &&
                     l_esbocs_pvt->check_signs_structure &&
-                    !s_check_signing_rights(l_esbocs, a_block, a_block_size, &l_signing_addr, false)) {
-                log_it(L_ATT, "Restricted emergency block signer %s",
-                                dap_chain_hash_fast_to_str_static(&l_signing_addr.data.hash_fast));
+                    !s_check_signing_rights(l_esbocs, a_block, l_block_size, &l_signing_addr, false)) {
+                if (l_esbocs_pvt->debug) {
+                    char l_block_hash_str[DAP_HASH_FAST_STR_SIZE];
+                    dap_hash_fast_to_str(a_block_hash, l_block_hash_str, DAP_HASH_FAST_STR_SIZE);
+                    log_it(L_ATT, "Restricted emergency block signer %s for block %s", dap_hash_fast_to_str_static(&l_signing_addr.data.hash_fast), l_block_hash_str);
+                }
                 l_ret = -5;
                 break;
             } else if (l_esbocs_pvt->check_signs_structure &&
-                    !s_check_signing_rights(l_esbocs, a_block, a_block_size, &l_signing_addr, false)) {
-                log_it(L_ATT, "Restricted block signer %s",
-                                dap_chain_hash_fast_to_str_static(&l_signing_addr.data.hash_fast));
+                    !s_check_signing_rights(l_esbocs, a_block, l_block_size, &l_signing_addr, false)) {
+                if (l_esbocs_pvt->debug) {
+                    char l_block_hash_str[DAP_HASH_FAST_STR_SIZE];
+                    dap_hash_fast_to_str(a_block_hash, l_block_hash_str, DAP_HASH_FAST_STR_SIZE);
+                    log_it(L_ATT, "Restricted block signer %s for block %s", dap_hash_fast_to_str_static(&l_signing_addr.data.hash_fast), l_block_hash_str);
+                }
                 l_ret = -5;
                 break;
             }
@@ -2892,12 +2892,8 @@ static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_bl
     a_block->hdr.meta_n_datum_n_signs_size = l_block_original;
 
     if (l_signs_verified_count < l_esbocs_pvt->min_validators_count) {
-        dap_hash_fast_t l_block_hash;
-        dap_hash_fast(a_block, a_block_size, &l_block_hash);
-        char l_block_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
-        dap_hash_fast_to_str(&l_block_hash, l_block_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE);
         debug_if(l_esbocs_pvt->debug, L_ERROR, "Corrupted block %s: not enough authorized signs: %u of %u",
-                    l_block_hash_str, l_signs_verified_count, l_esbocs_pvt->min_validators_count);
+                    dap_hash_fast_to_str_static(a_block_hash), l_signs_verified_count, l_esbocs_pvt->min_validators_count);
         return l_ret ? l_ret : -4;
     }
     return 0;
diff --git a/modules/type/blocks/dap_chain_block.c b/modules/type/blocks/dap_chain_block.c
index f1c6c7e8dc191cba147f4a8941bbf184e2125020..181a53bf6dc83679a356af312e0fa348937e61dd 100644
--- a/modules/type/blocks/dap_chain_block.c
+++ b/modules/type/blocks/dap_chain_block.c
@@ -103,23 +103,29 @@ dap_chain_block_t *dap_chain_block_new(dap_chain_hash_fast_t *a_prev_block, size
  */
 size_t s_block_get_datum_offset(const dap_chain_block_t *a_block, size_t a_block_size)
 {
-    if( a_block_size < sizeof(a_block->hdr) ){
-        log_it(L_ERROR, "Can't get datum offset: corrupted block size %zu / header size %zu", a_block_size, sizeof (a_block->hdr));
+    assert(a_block && a_block_size);
+    if (a_block_size < sizeof(a_block->hdr)) {
+        log_it(L_ERROR, "Can't get datum offset: corrupted block size %zu / header size %zu", a_block_size, sizeof(a_block->hdr));
         return 0;
     }
     size_t l_offset = 0;
-    dap_chain_block_meta_t * l_meta=NULL;
-    for( size_t i = 0; i< a_block->hdr.meta_count &&
-                       l_offset < (a_block_size-sizeof (a_block->hdr)) &&
-                       sizeof (l_meta->hdr) <=  (a_block_size-sizeof (a_block->hdr)) - l_offset ; i++){
-        l_meta =(dap_chain_block_meta_t *) (a_block->meta_n_datum_n_sign +l_offset);
+    dap_chain_block_meta_t *l_meta = NULL;
+    for (size_t i = 0; i < a_block->hdr.meta_count; i++) {
+        if (sizeof(a_block->hdr) + l_offset + sizeof(dap_chain_block_meta_t) > a_block_size)
+            return 0;
+        if (l_offset + sizeof(dap_chain_block_meta_t) < l_offset)
+            return 0;
+        l_meta = (dap_chain_block_meta_t *)(a_block->meta_n_datum_n_sign + l_offset);
+        l_offset += sizeof(dap_chain_block_meta_t);
         size_t l_meta_data_size = l_meta->hdr.data_size;
-        if (l_meta_data_size + sizeof (l_meta->hdr) + l_offset <= (a_block_size-sizeof (a_block->hdr)) ){
-            l_offset += sizeof (l_meta->hdr);
-            l_offset += l_meta_data_size;
-        }else
-            l_offset = (a_block_size-sizeof (a_block->hdr));
+        if (sizeof(a_block->hdr) + l_offset + l_meta_data_size > a_block_size)
+            return 0;
+        if (l_offset + l_meta_data_size < l_offset)
+            return 0;
+        l_offset += l_meta_data_size;
     }
+    if (sizeof(a_block->hdr) + l_offset > a_block_size)
+        return 0;
     return l_offset;
 }
 
@@ -133,10 +139,8 @@ size_t s_block_get_datum_offset(const dap_chain_block_t *a_block, size_t a_block
  */
 size_t dap_chain_block_datum_add(dap_chain_block_t ** a_block_ptr, size_t a_block_size, dap_chain_datum_t * a_datum, size_t a_datum_size)
 {
-    assert(a_block_ptr);
-    dap_chain_block_t * l_block = *a_block_ptr;
-    assert(l_block);
-    assert(a_datum_size);
+    dap_chain_block_t *l_block = *a_block_ptr;
+    dap_return_val_if_fail(l_block && a_block_size && a_datum && a_datum_size, a_block_size);
     size_t l_offset = s_block_get_datum_offset(l_block,a_block_size);
     dap_chain_datum_t * l_datum =(dap_chain_datum_t *) (l_block->meta_n_datum_n_sign + l_offset);
     // Pass all datums to the end
@@ -167,7 +171,7 @@ size_t dap_chain_block_datum_add(dap_chain_block_t ** a_block_ptr, size_t a_bloc
         *a_block_ptr = l_block = DAP_REALLOC(l_block, sizeof(l_block->hdr) + l_offset + a_datum_size);
         if (!l_block) {
             log_it(L_CRITICAL, "Memory reallocation error");
-            return 0;
+            return a_block_size;
         }
         memcpy(l_block->meta_n_datum_n_sign + l_offset, a_datum, a_datum_size);
         l_offset += a_datum_size;
@@ -248,38 +252,26 @@ size_t dap_chain_block_datum_del_by_hash(dap_chain_block_t ** a_block_ptr, size_
  */
 size_t dap_chain_block_get_sign_offset(const dap_chain_block_t *a_block, size_t a_block_size)
 {
-    assert(a_block);
-    assert(a_block_size);
+    dap_return_val_if_fail(a_block && a_block_size, 0);
     if (a_block_size <= sizeof(a_block->hdr)) {
         log_it(L_ERROR, "Get sign: corrupted block, block size %zd is lesser than block header size %zd", a_block_size,sizeof (a_block->hdr));
         return 0;
     }
-
     size_t l_offset = s_block_get_datum_offset(a_block, a_block_size);
-    dap_chain_datum_t * l_datum =(dap_chain_datum_t *) (a_block->meta_n_datum_n_sign + l_offset);
     // Pass all datums to the end
-    for(size_t n=0; n<a_block->hdr.datum_count && l_offset< (a_block_size-sizeof (a_block->hdr)) ; n++){
-        size_t l_datum_size = dap_chain_datum_size(l_datum);
-
-        // Check if size 0
-        if(! l_datum_size){
-            log_it(L_ERROR,"Datum size is 0, smth is corrupted in block");
+    for (size_t n = 0; n < a_block->hdr.datum_count; n++) {
+        if (sizeof(a_block->hdr) + l_offset + sizeof(dap_chain_datum_t) > a_block_size)
             return 0;
-        }
-        // Check if size of of block size
-        if ( (l_datum_size+l_offset) > (a_block_size-sizeof (a_block->hdr)) ){
-            log_it(L_ERROR,"Datum size is too big %zu thats with offset %zu is bigger than block size %zu", l_datum_size, l_offset, a_block_size);
+        dap_chain_datum_t *l_datum =(dap_chain_datum_t *)(a_block->meta_n_datum_n_sign + l_offset);
+        size_t l_datum_size = dap_chain_datum_size(l_datum);
+        if (l_offset + l_datum_size <= l_offset)
             return 0;
-        }
         l_offset += l_datum_size;
-        // Updae current datum pointer, if it was deleted - we also need to update it after realloc
-        l_datum =(dap_chain_datum_t *) (a_block->meta_n_datum_n_sign + l_offset);
     }
-    if (l_offset> (a_block_size-sizeof (a_block->hdr))){
-        log_it(L_ERROR,"Offset %zd with block header %zu is bigger than block size %zu", l_offset,sizeof (a_block->hdr),a_block_size);
+    if (sizeof(a_block->hdr) + l_offset > a_block_size) {
+        log_it(L_ERROR, "Offset %zd with block header %zu is bigger than block size %zu", l_offset, sizeof(a_block->hdr), a_block_size);
         return 0;
     }
-
     return l_offset;
 }
 
@@ -345,7 +337,7 @@ size_t dap_chain_block_get_signs_count(const dap_chain_block_t * a_block, size_t
     assert(a_block_size);
     uint16_t l_sign_count = 0;
     size_t l_offset = dap_chain_block_get_sign_offset(a_block,a_block_size);
-    for ( ; l_offset+sizeof(a_block->hdr) < a_block_size; l_sign_count++) {
+    for ( ; l_offset + sizeof(a_block->hdr) + sizeof(dap_sign_t) < a_block_size; l_sign_count++) {
         dap_sign_t *l_sign = (dap_sign_t *)(a_block->meta_n_datum_n_sign + l_offset);
         size_t l_sign_size = dap_sign_get_size(l_sign);
         if (!l_sign_size){
@@ -356,6 +348,8 @@ size_t dap_chain_block_get_signs_count(const dap_chain_block_t * a_block, size_t
             log_it(L_ERROR, "Corrupted sign #%hu size %zu", l_sign_count, l_sign_size);
             return l_sign_count;
         }
+        if (l_offset + l_sign_size <= l_offset)
+            return l_sign_count;
         l_offset += l_sign_size;
     }
     return l_sign_count;
@@ -365,15 +359,15 @@ bool dap_chain_block_sign_match_pkey(const dap_chain_block_t *a_block, size_t a_
 {
     dap_return_val_if_fail(a_block && a_block_size, false);
     size_t l_offset = dap_chain_block_get_sign_offset(a_block, a_block_size);
-    while (l_offset + sizeof(a_block->hdr) < a_block_size) {
+    while (l_offset + sizeof(a_block->hdr) + sizeof(dap_sign_t) < a_block_size) {
         dap_sign_t *l_sign = (dap_sign_t *)(a_block->meta_n_datum_n_sign + l_offset);
         size_t l_sign_size = dap_sign_get_size(l_sign);
-        if (!l_sign_size) {
-            log_it(L_WARNING, "Empty or corrupted sign");
+        if (!l_sign_size || l_sign_size + l_offset + sizeof(a_block->hdr) > a_block_size)
             return false;
-        }
         if (dap_pkey_compare_with_sign(a_sign_pkey, l_sign))
             return true;
+        if (l_offset + l_sign_size < l_offset)
+            return false;
         l_offset += l_sign_size;
     }
     return false;
diff --git a/modules/type/blocks/dap_chain_block_chunk.c b/modules/type/blocks/dap_chain_block_chunk.c
deleted file mode 100644
index 697a99523b062e6a7c61a392aa4799da611426c7..0000000000000000000000000000000000000000
--- a/modules/type/blocks/dap_chain_block_chunk.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Authors:
- * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
- * DeM Labs Ltd   https://demlabs.net
- * Copyright  (c) 2020
- * All rights reserved.
-
- This file is part of DAP SDK the open source project
-
-    DAP SDK is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    DAP SDK is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with any DAP SDK based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#include "dap_common.h"
-#include "dap_strfuncs.h"
-#include "dap_global_db.h"
-#include "dap_chain_block_chunk.h"
-
-#define LOG_TAG "dap_chain_block_chunk"
-
-/**
- * @brief dap_chain_block_chunks_create
- * @param a_blocks
- * @return
- */
-dap_chain_block_chunks_t * dap_chain_block_chunks_create(dap_chain_cs_blocks_t * a_blocks)
-{
-    assert(a_blocks);
-    assert(a_blocks->chain);
-    dap_chain_block_chunks_t * l_ret = DAP_NEW_Z(dap_chain_block_chunks_t);
-    if (!l_ret) {
-        log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-        return NULL;
-    }
-    l_ret->blocks = a_blocks;
-    l_ret->gdb_group = dap_strdup_printf("local.%s.%s.block.chunks",a_blocks->chain->net_name, a_blocks->chain->name );
-
-    size_t l_objs_count =0;
-    dap_global_db_obj_t * l_objs= dap_global_db_get_all_sync(l_ret->gdb_group, &l_objs_count);
-    for(size_t n=0; n< l_objs_count; n++){
-        dap_hash_fast_t l_block_hash;
-        dap_chain_hash_fast_from_str(l_objs[n].key, &l_block_hash);
-        dap_chain_block_cache_t *l_block_cache = dap_chain_block_cache_new(&l_block_hash, (dap_chain_block_t *)l_objs[n].value, l_objs[n].value_len, n + 1, true);
-        dap_chain_block_chunks_add(l_ret, l_block_cache );
-    }
-    dap_global_db_objs_delete(l_objs,l_objs_count);
-    return l_ret;
-}
-
-/**
- * @brief dap_chain_block_chunks_delete
- * @param a_chunks
- */
-void dap_chain_block_chunks_delete(dap_chain_block_chunks_t * a_chunks)
-{
-    dap_chain_block_cache_hash_t *l_block_cache_hash, *l_block_cache_hash_tmp;
-    for (dap_chain_block_chunk_t *l_chunk = a_chunks->chunks_last; l_chunk; l_chunk = l_chunk->prev) {
-        HASH_ITER(hh, l_chunk->block_cache_hash , l_block_cache_hash, l_block_cache_hash_tmp){
-        HASH_DEL(l_chunk->block_cache_hash, l_block_cache_hash);
-            DAP_DELETE(l_block_cache_hash);
-        }
-    }
-    dap_chain_block_cache_t* l_block_cache, *l_block_cache_tmp = NULL;
-    HASH_ITER(hh, a_chunks->cache , l_block_cache, l_block_cache_tmp) {
-        HASH_DEL(a_chunks->cache, l_block_cache);
-        dap_chain_block_cache_delete(l_block_cache);
-    }
-    DAP_DELETE(a_chunks->gdb_group);
-    DAP_DELETE(a_chunks);
-}
-
-
-/**
- * @brief dap_chain_block_chunks_add
- * @param a_chunks
- * @param a_block_cache
- * @return
- */
-void dap_chain_block_chunks_add(dap_chain_block_chunks_t * a_chunks,dap_chain_block_cache_t  * a_block_cache)
-{
-    if (!a_block_cache)
-        return;
-    dap_chain_block_cache_hash_t  * l_chunk_cache_hash = NULL;
-    dap_chain_block_cache_t * l_chunk_cache = NULL;
-    // Parse block and produce cache object
-    // Check if already present
-    HASH_FIND(hh, a_chunks->cache, &a_block_cache->block_hash, sizeof(dap_chain_hash_fast_t), l_chunk_cache);
-    if (l_chunk_cache){
-        log_it(L_WARNING, "Already present block %s in cache",a_block_cache->block_hash_str);
-        dap_chain_block_cache_delete(a_block_cache);
-        return;
-    }
-    // Save to GDB
-    //dap_global_db_set(a_chunks->gdb_group, a_block_cache->block_hash_str, a_block_cache->block, a_block_cache->block_size,
-    //                           false, NULL, NULL );
-
-    // And here we select chunk for the new block cache
-    bool l_is_chunk_found = false;
-    for (dap_chain_block_chunk_t * l_chunk = a_chunks->chunks_last; l_chunk; l_chunk = l_chunk->prev ){
-        if(dap_hash_fast_compare(&l_chunk->block_cache_top->block_hash, &a_block_cache->prev_hash ) ){
-            // Init cache-hash object
-            l_chunk_cache_hash = DAP_NEW_Z(dap_chain_block_cache_hash_t);
-            if (!l_chunk_cache_hash) {
-                log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                return;
-            }
-            l_chunk_cache_hash->block_cache=a_block_cache;
-            l_chunk_cache_hash->ts_created = time(NULL);
-            l_chunk_cache_hash->block_hash = a_block_cache->block_hash;
-            l_chunk_cache_hash->chunk = l_chunk;
-
-            // Update first block cache from the head
-            l_chunk->block_cache_top = a_block_cache;
-            // Add to selected chunk its hash object
-            HASH_ADD(hh,l_chunk->block_cache_hash , block_hash, sizeof (l_chunk_cache_hash->block_hash), l_chunk_cache_hash);
-
-            // Update chunk id to make it unique
-            dap_chain_hash_fast_t l_hash_new_data[2]={a_block_cache->block_hash,l_chunk->chunk_id };
-            dap_hash_fast(l_hash_new_data,sizeof (l_hash_new_data),&l_chunk->chunk_id);
-            l_is_chunk_found = true;
-        }
-    }
-
-    if ( ! l_is_chunk_found ) { // Don't found anything suitable - if so we create our own chunk
-        dap_chain_block_chunk_t * l_chunk = dap_chain_block_chunk_create(a_chunks);
-
-        // Init cache-hash object
-        l_chunk_cache_hash = DAP_NEW_Z(dap_chain_block_cache_hash_t);
-        if (!l_chunk_cache_hash) {
-            log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-            return;
-        }
-        l_chunk_cache_hash->block_cache=a_block_cache;
-        l_chunk_cache_hash->ts_created = time(NULL);
-        l_chunk_cache_hash->block_hash = a_block_cache->block_hash;
-        l_chunk_cache_hash->chunk = l_chunk;
-
-        // Update first block cache from the head
-        l_chunk->block_cache_top = a_block_cache;
-        // Add to selected chunk its hash object
-        HASH_ADD(hh,l_chunk->block_cache_hash , block_hash, sizeof (l_chunk_cache_hash->block_hash), l_chunk_cache_hash);
-
-        // Update chunk id to make it unique
-        dap_chain_hash_fast_t l_hash_new_data[2]={a_block_cache->block_hash,l_chunk->chunk_id };
-        dap_hash_fast(l_hash_new_data,sizeof (l_hash_new_data),&l_chunk->chunk_id);
-    }
-
-
-    // Add object itself to all-chunks cache
-    HASH_ADD(hh,a_chunks->cache ,block_hash ,sizeof (a_block_cache->block_hash), a_block_cache);
-}
-
-/**
- * @brief dap_chain_block_chunk_create
- * @param a_chunks
- * @return
- */
-dap_chain_block_chunk_t * dap_chain_block_chunk_create(dap_chain_block_chunks_t * a_chunks)
-{
-    dap_chain_block_chunk_t * l_chunk = DAP_NEW_Z(dap_chain_block_chunk_t);
-    if (!l_chunk) {
-        log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-        return NULL;
-    }
-    // Add in tail
-    l_chunk->prev = a_chunks->chunks_first;
-    if (a_chunks->chunks_first){
-        l_chunk->next = a_chunks->chunks_first->next;
-        if (! l_chunk->next)
-            a_chunks->chunks_last = l_chunk;
-        else
-            l_chunk->next->prev = l_chunk;
-    }else
-        a_chunks->chunks_last = l_chunk;
-    a_chunks->chunks_first = l_chunk;
-    return l_chunk;
-}
-
-/**
- * @brief dap_chain_block_chunk_delete
- * @param a_chunk
- */
-void dap_chain_block_chunk_delete( dap_chain_block_chunk_t * a_chunk)
-{
-    dap_chain_block_cache_hash_t  * l_cache_hash = NULL, *l_tmp = NULL;
-    HASH_ITER(hh, a_chunk->block_cache_hash, l_cache_hash, l_tmp){
-        // Clang bug at this, l_cache_hash should change at every loop cycle
-        HASH_DEL(a_chunk->block_cache_hash, l_cache_hash);
-        DAP_DELETE(l_cache_hash);
-    }
-    DAP_DELETE(a_chunk);
-}
-
-/**
- * @brief dap_chain_block_chunks_sort
- * @param a_chunks
- */
-void dap_chain_block_chunks_sort(dap_chain_block_chunks_t * a_chunks)
-{
-    // Sort chunk list beginning from the new one and bubble up the longest one on the top
-    size_t l_chunk_length_max=0;
-    //dap_chain_block_chunk_t * l_chunk_max = NULL;
-    for (dap_chain_block_chunk_t * l_chunk = a_chunks->chunks_first ; l_chunk; l_chunk = l_chunk? l_chunk->next: NULL ){
-        if(!l_chunk)
-            break;
-        size_t l_chunk_length = HASH_COUNT(l_chunk->block_cache_hash);
-        if (! l_chunk_length){
-            log_it(L_WARNING,"Chunk can't be empty, it must be deleted from chunks treshold");
-        }
-        if (l_chunk_length > l_chunk_length_max ){
-            //l_chunk_max = l_chunk;
-            l_chunk_length_max = l_chunk_length;
-        }else if (l_chunk_length == l_chunk_length_max ){
-            continue;
-        }else{
-            // Prev store
-            dap_chain_block_chunk_t * l_chunk_prev = l_chunk->prev;
-
-            // Link next with prev
-            if (l_chunk->next )
-                l_chunk->next->prev = l_chunk->prev;
-
-            dap_chain_block_chunk_t * l_chunk_prev_prev = NULL;
-
-            if (l_chunk_prev){
-                // Link prev with next
-                l_chunk_prev->next = l_chunk->next;
-                l_chunk_prev_prev = l_chunk_prev->prev;
-                // Link prev with current
-                l_chunk_prev->prev = l_chunk;
-                // Update first chunks
-                if ( ! l_chunk_prev_prev)
-                    a_chunks->chunks_first = l_chunk;
-            }
-
-            // Link current with prev
-            l_chunk->next = l_chunk->prev ;
-            l_chunk->prev = l_chunk_prev_prev;
-
-            // Replace previous with current
-            l_chunk = l_chunk_prev;
-
-            // Its the last chunk
-            if (l_chunk && ! l_chunk->next)
-                a_chunks->chunks_last = l_chunk;
-        }
-    }
-    log_it(L_INFO,"Chunks sorted: max tail %zd", l_chunk_length_max );
-
-}
diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c
index ea48d44a6ae9abfa95c2a993ff7cf133baf866c2..79b7469c6198db17eae8ac0c52ed880590025a31 100644
--- a/modules/type/blocks/dap_chain_cs_blocks.c
+++ b/modules/type/blocks/dap_chain_cs_blocks.c
@@ -28,8 +28,6 @@
 #include "dap_chain_cs_blocks.h"
 #include "dap_chain_block.h"
 #include "dap_chain_block_cache.h"
-#include "dap_chain_block_chunk.h"
-#include "dap_timerfd.h"
 #include "dap_cli_server.h"
 #include "dap_chain_node_cli_cmd.h"
 #include "dap_chain_mempool.h"
@@ -52,34 +50,29 @@ struct cs_blocks_hal_item {
     UT_hash_handle hh;
 };
 
-typedef struct dap_chain_cs_blocks_pvt
-{
+typedef struct dap_chain_cs_blocks_pvt {
     // Parent link
-    dap_chain_cs_blocks_t * cs_blocks;
+    dap_chain_cs_blocks_t *cs_blocks;
 
-    // All the blocks are here. In feature should be limited with 1000 when the rest would be loaded from file when needs them
-    dap_chain_block_cache_t * blocks;
+    // All the blocks are here
+    dap_chain_block_cache_t *blocks;
+     _Atomic uint64_t blocks_count;
 
+    // Brnches and forks
     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
+    // Datum search in blocks
+    dap_chain_block_datum_index_t *datum_index;
     pthread_rwlock_t datums_rwlock;
+     _Atomic uint64_t tx_count;
 
     dap_chain_hash_fast_t genesis_block_hash;
     dap_chain_hash_fast_t static_genesis_block_hash;
 
-    _Atomic uint64_t blocks_count;
-
-    time_t time_between_blocks_minimum; // Minimal time between blocks
     bool is_celled;
 
-    dap_timerfd_t *fill_timer;
-    uint64_t fill_timeout;
-
     pthread_rwlock_t rwlock;
     struct cs_blocks_hal_item *hal;
 } dap_chain_cs_blocks_pvt_t;
@@ -154,7 +147,9 @@ static dap_chain_block_t *s_new_block_move(dap_chain_cs_blocks_t *a_blocks, size
 //Work with atoms
 static uint64_t s_callback_count_atom(dap_chain_t *a_chain);
 static dap_list_t *s_callback_get_atoms(dap_chain_t *a_chain, size_t a_count, size_t a_page, bool a_reverse);
-
+// Get TXs callbacks
+static uint64_t s_callback_count_txs(dap_chain_t *a_chain);
+static dap_list_t *s_callback_get_txs(dap_chain_t *a_chain, size_t a_count, size_t a_page, bool a_reverse);
 static int s_chain_cs_blocks_new(dap_chain_t * a_chain, dap_config_t * a_chain_config);
 
 static bool s_seed_mode = false;
@@ -297,6 +292,9 @@ static int s_chain_cs_blocks_new(dap_chain_t *a_chain, dap_config_t *a_chain_con
 
     a_chain->callback_count_atom = s_callback_count_atom;
     a_chain->callback_get_atoms = s_callback_get_atoms;
+    a_chain->callback_count_tx = s_callback_count_txs;
+    a_chain->callback_get_txs = s_callback_get_txs;
+
 
     l_cs_blocks->callback_new_block_move = s_new_block_move;
 
@@ -317,7 +315,7 @@ static int s_chain_cs_blocks_new(dap_chain_t *a_chain, dap_config_t *a_chain_con
             log_it( L_ERROR, "Can't read hash from genesis_block \"%s\", ret code %d ", l_genesis_blocks_hash_str, lhr);
         }
     }
-    l_cs_blocks_pvt->is_celled = dap_config_get_item_bool_default(a_chain_config,"blocks","is_celled",false);
+    l_cs_blocks_pvt->is_celled = dap_config_get_item_bool_default(a_chain_config, "blocks", "is_celled", false);
     const char * l_static_genesis_blocks_hash_str = dap_config_get_item_str_default(a_chain_config,"blocks","static_genesis_block",NULL);
     if ( l_static_genesis_blocks_hash_str ){
         int lhr;
@@ -325,10 +323,6 @@ static int s_chain_cs_blocks_new(dap_chain_t *a_chain, dap_config_t *a_chain_con
             log_it( L_ERROR, "Can't read hash from static_genesis_block \"%s\", ret code %d ", l_static_genesis_blocks_hash_str, lhr);
         }
     }
-    l_cs_blocks_pvt->chunks = dap_chain_block_chunks_create(l_cs_blocks);
-
-    l_cs_blocks_pvt->fill_timeout = dap_config_get_item_uint64_default(a_chain_config, "blocks", "fill_timeout", 60) * 1000; // 1 min
-    l_cs_blocks_pvt->blocks_count = 0;
 
     uint16_t l_list_len = 0;
     const char **l_hard_accept_list = dap_config_get_array_str(a_chain_config, "blocks", "hard_accept_list", &l_list_len);
@@ -1417,7 +1411,6 @@ static void s_callback_delete(dap_chain_t * a_chain)
     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);
     log_it(L_INFO, "Block destructed");
@@ -1458,11 +1451,7 @@ static void s_callback_cs_blocks_purge(dap_chain_t *a_chain)
         l_datum_index = NULL;
     }
     pthread_rwlock_unlock(&PVT(l_blocks)->datums_rwlock);
-
-    dap_chain_block_chunks_delete(PVT(l_blocks)->chunks);
     dap_chain_cell_delete_all(a_chain);
-    //dap_chain_cell_delete_all_and_free_file(a_chain);
-    PVT(l_blocks)->chunks = dap_chain_block_chunks_create(l_blocks);
 }
 
 /**
@@ -1494,6 +1483,8 @@ static int s_add_atom_datums(dap_chain_cs_blocks_t *a_blocks, dap_chain_block_ca
         dap_hash_fast_t *l_datum_hash = a_block_cache->datum_hash + i;
         int l_res = dap_chain_datum_add(a_blocks->chain, l_datum, l_datum_size, l_datum_hash);
         l_ret++;
+        if (l_datum->header.type_id == DAP_CHAIN_DATUM_TX)
+            PVT(a_blocks)->tx_count++;
         // Save datum hash -> block_hash link in hash table
         dap_chain_block_datum_index_t *l_datum_index = DAP_NEW_Z(dap_chain_block_datum_index_t);
         if (!l_datum_index) {
@@ -1805,135 +1796,165 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da
  * @param a_atom_size
  * @return
  */
-static dap_chain_atom_verify_res_t s_callback_atom_verify(dap_chain_t * a_chain, dap_chain_atom_ptr_t a_atom , size_t a_atom_size, dap_chain_hash_fast_t * a_atom_hash)
+static dap_chain_atom_verify_res_t s_callback_atom_verify(dap_chain_t *a_chain, dap_chain_atom_ptr_t a_atom, size_t a_atom_size, dap_chain_hash_fast_t *a_atom_hash)
 {
+    dap_return_val_if_fail(a_chain && a_atom && a_atom_size && a_atom_hash, ATOM_REJECT);
     dap_chain_cs_blocks_t * l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain);
     assert(l_blocks);
-    dap_chain_cs_blocks_pvt_t * l_blocks_pvt = PVT(l_blocks);
+    dap_chain_cs_blocks_pvt_t *l_blocks_pvt = PVT(l_blocks);
     assert(l_blocks_pvt);
-    dap_chain_block_t * l_block = (dap_chain_block_t *) a_atom;
+    dap_chain_block_t * l_block = (dap_chain_block_t *)a_atom;
     dap_chain_hash_fast_t l_block_hash = *a_atom_hash;
 
-    if(sizeof (l_block->hdr) >= a_atom_size){
-        log_it(L_WARNING,"Size of block is %zd that is equal or less then block's header size %zd",a_atom_size,sizeof (l_block->hdr));
-        return  ATOM_REJECT;
+    if (sizeof(l_block->hdr) >= a_atom_size) {
+        log_it(L_WARNING, "Size of block %s is %zd that is equal or less then block's header size %zd",
+                                dap_hash_fast_to_str_static(a_atom_hash), a_atom_size, sizeof(l_block->hdr));
+        return ATOM_REJECT;
     }
-
-    // Hard accept list
-    if (l_blocks_pvt->hal) {
+    size_t l_offset = dap_chain_block_get_sign_offset(l_block, a_atom_size);
+    if (!l_offset) {
+        log_it(L_WARNING, "Block %s with size %zu parsing error", dap_hash_fast_to_str_static(a_atom_hash), a_atom_size);
+        return ATOM_REJECT;
+    }
+    if ((l_block->hdr.version >= 2 || /* Old bug, crutch for it */ l_block->hdr.meta_n_datum_n_signs_size != l_offset) &&
+            l_block->hdr.meta_n_datum_n_signs_size + sizeof(l_block->hdr) != a_atom_size) {
+        // Hard accept list
         struct cs_blocks_hal_item *l_hash_found = NULL;
         HASH_FIND(hh, l_blocks_pvt->hal, &l_block_hash, sizeof(l_block_hash), l_hash_found);
-        if (l_hash_found) {
-            return ATOM_ACCEPT;
+        if (!l_hash_found) {
+            log_it(L_WARNING, "Incorrect size %zu of block %s, expected %zu", l_block->hdr.meta_n_datum_n_signs_size + sizeof(l_block->hdr),
+                                                                    dap_hash_fast_to_str_static(a_atom_hash), a_atom_size);
+            return ATOM_REJECT;
         }
     }
-
-    if (l_block->hdr.ts_created > dap_time_now() + 60) {
-        log_it(L_WARNING, "Incorrect block timestamp");
-        return  ATOM_REJECT;
+    while (sizeof(l_block->hdr) + l_offset + sizeof(dap_sign_t) < a_atom_size) {
+        dap_sign_t *l_sign = (dap_sign_t *)((byte_t *)a_atom + sizeof(l_block->hdr) + l_offset);
+        size_t l_sign_size = dap_sign_get_size(l_sign);
+        if (l_offset + l_sign_size <= l_offset)
+            break;
+        l_offset += l_sign_size;
+    }
+    if (l_offset + sizeof(l_block->hdr) != a_atom_size) {
+        log_it(L_WARNING, "Incorrect size %zu of block %s, expected %zu", l_offset + sizeof(l_block->hdr),
+                                                                dap_hash_fast_to_str_static(a_atom_hash), a_atom_size);
+        return ATOM_REJECT;
     }
 
-    // 2nd level consensus
-    if(l_blocks->callback_block_verify)
-        if (l_blocks->callback_block_verify(l_blocks, l_block, a_atom_size)){
-             debug_if(s_debug_more, L_WARNING, "Block rejected by block verificator.");
-            return ATOM_REJECT;
-        }   
+    if (!l_block->hdr.ts_created || l_block->hdr.ts_created > dap_time_now() + 600) {
+        log_it(L_WARNING, "Incorrect block %s timestamp", dap_hash_fast_to_str_static(a_atom_hash));
+        return ATOM_REJECT;
+    }
 
+    int ret = ATOM_MOVE_TO_THRESHOLD;
 // Parse metadata
     bool l_is_genesis = dap_chain_block_meta_get(l_block, a_atom_size, DAP_CHAIN_BLOCK_META_GENESIS);
-    dap_hash_t *l_prev_hash_meta_data = (dap_hash_t *)dap_chain_block_meta_get(l_block, a_atom_size, DAP_CHAIN_BLOCK_META_PREV);
-    dap_hash_t l_block_prev_hash = l_prev_hash_meta_data ? *l_prev_hash_meta_data : (dap_hash_t){};
-
-    char* l_block_str = dap_chain_hash_fast_to_str_new(&l_block_hash);
-    char* l_prev_block_str = dap_chain_hash_fast_to_str_new(&l_block_prev_hash);
-
-    debug_if(s_debug_more, L_DEBUG,"Verify new block with hash %s. previous block %s", l_block_str, l_prev_block_str);
-    DAP_DELETE(l_block_str);
-    DAP_DELETE(l_prev_block_str);
     // genesis or seed mode
     if (l_is_genesis) {
-        if (!PVT(l_blocks)->blocks) {
+        if (PVT(l_blocks)->blocks) {
+            log_it(L_WARNING, "Can't accept genesis block %s: already present data in blockchain", dap_hash_fast_to_str_static(a_atom_hash));
+            return ATOM_REJECT;
+        }
 #ifndef DAP_CHAIN_BLOCKS_TEST
-            if (s_seed_mode)
-                log_it(L_NOTICE, "Accepting new genesis block");
-
-            else if(dap_hash_fast_compare(&l_block_hash,&PVT(l_blocks)->static_genesis_block_hash)
-                    && !dap_hash_fast_is_blank(&l_block_hash))
-                log_it(L_NOTICE, "Accepting static genesis block");
-            else{
-                char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE] = { '\0' };
-                dap_hash_fast_to_str(&l_block_hash, l_hash_str, sizeof(l_hash_str));
-                log_it(L_WARNING,"Cant accept genesis block: seed mode not enabled or hash mismatch with static genesis block %s in configuration", l_hash_str);
-                return ATOM_REJECT;
-            }
+        if (s_seed_mode)
+            log_it(L_NOTICE, "Accepting new genesis block %s", dap_hash_fast_to_str_static(a_atom_hash));
+        else if(dap_hash_fast_compare(&l_block_hash, &PVT(l_blocks)->static_genesis_block_hash)
+                && !dap_hash_fast_is_blank(&l_block_hash))
+            log_it(L_NOTICE, "Accepting static genesis block %s", dap_hash_fast_to_str_static(a_atom_hash));
+        else {
+            char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
+            dap_hash_fast_to_str(&PVT(l_blocks)->static_genesis_block_hash, l_hash_str, sizeof(l_hash_str));
+            log_it(L_WARNING, "Can't accept genesis block %s: seed mode not enabled or hash mismatch with static genesis block %s in configuration",
+                                dap_hash_fast_to_str_static(a_atom_hash), l_hash_str);
+            return ATOM_REJECT;
+        }
 #else
-            PVT(l_blocks)->genesis_block_hash = *a_atom_hash;
+        PVT(l_blocks)->genesis_block_hash = *a_atom_hash;
 #endif
-            debug_if(s_debug_more,L_DEBUG,"%s","Accepting new genesis block");
-            return ATOM_ACCEPT;
-        } else {
-            log_it(L_WARNING,"Cant accept genesis block: already present data in blockchain");
+        ret = ATOM_ACCEPT;
+    } else {
+        dap_hash_t *l_prev_hash_meta_data = (dap_hash_t *)dap_chain_block_meta_get(l_block, a_atom_size, DAP_CHAIN_BLOCK_META_PREV);
+        if (!l_prev_hash_meta_data) {
+            log_it(L_WARNING, "Block %s isn't a genesis one but not contains previous block hash in metadata", dap_hash_fast_to_str_static(a_atom_hash));
             return ATOM_REJECT;
         }
-    } else {
-        dap_chain_block_cache_t *l_bcache_last = PVT(l_blocks)->blocks ? PVT(l_blocks)->blocks->hh.tbl->tail->prev : NULL;
-        l_bcache_last = l_bcache_last ? l_bcache_last->hh.next : PVT(l_blocks)->blocks;
-
+        dap_hash_t l_block_prev_hash = *l_prev_hash_meta_data;
+        if (s_debug_more) {
+            char l_prev_block_hash_str[DAP_HASH_FAST_STR_SIZE];
+            dap_hash_fast_to_str(&l_block_prev_hash, l_prev_block_hash_str, DAP_HASH_FAST_STR_SIZE);
+            log_it(L_DEBUG, "Verify new block with hash %s. Previous block hash is %s", dap_hash_fast_to_str_static(a_atom_hash), l_prev_block_hash_str);
+        }
+        dap_chain_block_cache_t *l_bcache_last = HASH_LAST(PVT(l_blocks)->blocks);
         if (l_bcache_last && dap_hash_fast_compare(&l_bcache_last->block_hash, &l_block_prev_hash))
-            return ATOM_ACCEPT;
-
-        // search block and previous block in forked branch
-        pthread_rwlock_rdlock(& PVT(l_blocks)->rwlock);
-        for (size_t i = 0; i < PVT(l_blocks)->forked_br_cnt; i++){
-            dap_chain_block_forked_branch_t *l_cur_branch = PVT(l_blocks)->forked_branches[i];
-            dap_chain_block_forked_branch_atoms_table_t *l_item = NULL;
-            // Check block already present in forked branch
-            HASH_FIND(hh, l_cur_branch->forked_branch_atoms, &l_block_hash, sizeof(dap_hash_fast_t), l_item);
-            if (l_item && dap_hash_fast_compare(&l_item->block_hash, &l_block_hash)){
-                debug_if(s_debug_more,L_DEBUG,"%s","Block already exist in forked branch.");
-                pthread_rwlock_unlock(& PVT(l_blocks)->rwlock);
-                return ATOM_PASS;
-            } 
-            l_item = NULL;
-            // Find previous block is last block in current branch
-            HASH_FIND(hh, l_cur_branch->forked_branch_atoms, &l_block_prev_hash, sizeof(dap_hash_fast_t), l_item);
-            if (l_item && l_item->hh.next != NULL){
-                pthread_rwlock_unlock(& PVT(l_blocks)->rwlock);
-                debug_if(s_debug_more,L_DEBUG,"%s","Found previous block in forked branch. Can't add block into branch because previous block is not last in the branch.");
-                return ATOM_PASS;
-            } else if (l_item && l_item->hh.next == NULL) {
-                pthread_rwlock_unlock(& PVT(l_blocks)->rwlock);
-                debug_if(s_debug_more,L_DEBUG,"%s","Accept block to a forked branch.");
-                return ATOM_ACCEPT;
+            ret = ATOM_ACCEPT;
+        else { // search block and previous block in forked branch
+            pthread_rwlock_rdlock(& PVT(l_blocks)->rwlock);
+            for (size_t i = 0; i < PVT(l_blocks)->forked_br_cnt; i++){
+                dap_chain_block_forked_branch_t *l_cur_branch = PVT(l_blocks)->forked_branches[i];
+                dap_chain_block_forked_branch_atoms_table_t *l_item = NULL;
+                // Check block already present in forked branch
+                HASH_FIND(hh, l_cur_branch->forked_branch_atoms, &l_block_hash, sizeof(dap_hash_fast_t), l_item);
+                if (l_item) {
+                    debug_if(s_debug_more,L_DEBUG,"%s","Block already exist in forked branch.");
+                    ret = ATOM_PASS;
+                    break;
+                }
+                l_item = NULL;
+                // Find previous block is last block in current branch
+                HASH_FIND(hh, l_cur_branch->forked_branch_atoms, &l_block_prev_hash, sizeof(dap_hash_fast_t), l_item);
+                if (!l_item)
+                    continue;
+                if (l_item->hh.next) {
+                    debug_if(s_debug_more,L_DEBUG,"%s","Found previous block in forked branch. Can't add block into branch because previous block is not last in the branch.");
+                    ret = ATOM_PASS;
+                    break;
+                } else {
+                    debug_if(s_debug_more,L_DEBUG,"%s","Accept block to a forked branch.");
+                    ret = ATOM_ACCEPT;
+                    break;
+                }
             }
-        }
+            if (ret == ATOM_MOVE_TO_THRESHOLD) {
+                // search block and previous block in main branch
+                unsigned l_checked_atoms_cnt = DAP_FORK_MAX_DEPTH;
+                for (dap_chain_block_cache_t *l_tmp = l_bcache_last; l_tmp && l_checked_atoms_cnt; l_tmp = l_tmp->hh.prev, l_checked_atoms_cnt--){
+                    if(dap_hash_fast_compare(&l_tmp->block_hash, &l_block_hash)){
+                        debug_if(s_debug_more,L_DEBUG,"%s","Block is already exist in main branch.");
+                        ret = ATOM_PASS;
+                        break;
+                    }
 
-        // search block and previous block in main branch
-        unsigned l_checked_atoms_cnt = DAP_FORK_MAX_DEPTH;
-        for (dap_chain_block_cache_t *l_tmp = l_bcache_last; l_tmp && l_checked_atoms_cnt; l_tmp = l_tmp->hh.prev, l_checked_atoms_cnt--){
-            if(dap_hash_fast_compare(&l_tmp->block_hash, &l_block_hash)){
-                pthread_rwlock_unlock(& PVT(l_blocks)->rwlock);
-                debug_if(s_debug_more,L_DEBUG,"%s","Block is already exist in main branch.");
-                return ATOM_PASS;
+                    if (dap_hash_fast_compare(&l_tmp->block_hash, &l_block_prev_hash)) {
+                        if (l_tmp->hh.next) {
+                            debug_if(s_debug_more,L_DEBUG,"%s","New fork!");
+                            ret = ATOM_FORK;
+                            break;
+                        }
+                        debug_if(s_debug_more,L_DEBUG,"%s","Accept block to a main branch.");
+                        ret = ATOM_ACCEPT;
+                        break;
+                    }
+                }
             }
+            pthread_rwlock_unlock(&PVT(l_blocks)->rwlock);
+        }
+    }
 
-            if (dap_hash_fast_compare(&l_tmp->block_hash, &l_block_prev_hash)){
-                if (l_tmp->hh.next != NULL){
-                    pthread_rwlock_unlock(& PVT(l_blocks)->rwlock);
-                    debug_if(s_debug_more,L_DEBUG,"%s","New fork!");
-                    return ATOM_FORK;
-                } else {
-                    pthread_rwlock_unlock(& PVT(l_blocks)->rwlock);
-                    debug_if(s_debug_more,L_DEBUG,"%s","Accept block to a main branch.");
-                    return ATOM_ACCEPT;
-                }
+    if (ret == ATOM_FORK || ret == ATOM_ACCEPT) {
+        // 2nd level consensus
+        if (l_blocks->callback_block_verify && l_blocks->callback_block_verify(l_blocks, l_block, a_atom_hash, /* Old bug, crutch for it */ a_atom_size)) {
+            // Hard accept list
+            struct cs_blocks_hal_item *l_hash_found = NULL;
+            HASH_FIND(hh, l_blocks_pvt->hal, &l_block_hash, sizeof(l_block_hash), l_hash_found);
+            if (!l_hash_found) {
+                log_it(L_WARNING, "Block %s rejected by block verificator", dap_hash_fast_to_str_static(a_atom_hash));
+                return ATOM_REJECT;
             }
         }
+    } else if (ret == ATOM_MOVE_TO_THRESHOLD) {
+        debug_if(s_debug_more,L_DEBUG,"%s","Can't find valid previous block in chain or forked branches.");
+        return ATOM_REJECT;
     }
-    debug_if(s_debug_more,L_DEBUG,"%s","Can't find valid previous block in chain or forked branches.");
-    pthread_rwlock_unlock(& PVT(l_blocks)->rwlock);
-    return ATOM_REJECT;
+    return ret;
 }
 
 /**
@@ -2415,3 +2436,34 @@ static uint256_t s_callback_calc_reward(dap_chain_t *a_chain, dap_hash_fast_t *a
     DIV_256(l_ret, GET_256_FROM_64(s_block_timediff_unit_size * l_signs_count), &l_ret);
     return l_ret;
 }
+
+static uint64_t s_callback_count_txs(dap_chain_t *a_chain)
+{
+    return PVT(DAP_CHAIN_CS_BLOCKS(a_chain))->tx_count;
+}
+
+
+static dap_list_t *s_callback_get_txs(dap_chain_t *a_chain, size_t a_count, size_t a_page, bool a_reverse)
+{
+    UNUSED(a_reverse); // TODO
+    size_t l_count = s_callback_count_txs(a_chain);
+    size_t l_offset = a_count * a_page;
+    if (l_offset > l_count)
+        return NULL;
+    if (a_page < 2)
+        l_offset = 0;
+    dap_list_t *l_list = NULL;
+    size_t l_counter = 0;
+    size_t l_end = l_offset + a_count;
+    for (dap_chain_block_datum_index_t *it = PVT(DAP_CHAIN_CS_BLOCKS(a_chain))->datum_index;
+                it && l_counter < l_end;
+                it = it->hh.next) {
+        dap_chain_datum_t *l_datum = it->block_cache->datum[it->datum_index];
+        if (l_datum->header.type_id == DAP_CHAIN_DATUM_TX && l_counter++ >= l_offset) {
+            dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)l_datum->data;
+            l_list = dap_list_append(l_list, l_tx);
+        }
+    }
+    return l_list;
+}
+
diff --git a/modules/type/blocks/include/dap_chain_block.h b/modules/type/blocks/include/dap_chain_block.h
index 519b655c85ed90f61657cc85543473fcece94e8b..a0407e390a52d9a2a759d96fd0ee9dca63d17271 100644
--- a/modules/type/blocks/include/dap_chain_block.h
+++ b/modules/type/blocks/include/dap_chain_block.h
@@ -83,6 +83,8 @@ typedef struct  dap_chain_block{
     uint8_t meta_n_datum_n_sign[]; // Here are: metadata, datum sections and verificator signatures
 } DAP_ALIGN_PACKED dap_chain_block_t;
 
+DAP_STATIC_INLINE size_t dap_chain_block_get_size(dap_chain_block_t *a_block) { return sizeof(a_block->hdr) + a_block->hdr.meta_n_datum_n_signs_size; }
+
 // Init module
 int dap_chain_block_init();
 // Deinit module
diff --git a/modules/type/blocks/include/dap_chain_block_chunk.h b/modules/type/blocks/include/dap_chain_block_chunk.h
deleted file mode 100644
index d2e21a898dc82318871b66e1d7791333e75fad91..0000000000000000000000000000000000000000
--- a/modules/type/blocks/include/dap_chain_block_chunk.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Authors:
- * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
- * DeM Labs Ltd   https://demlabs.net
- * Copyright  (c) 2020
- * All rights reserved.
-
- This file is part of DAP SDK the open source project
-
-    DAP SDK is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    DAP SDK is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with any DAP SDK based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#pragma once
-#include "dap_chain_block_cache.h"
-#include "dap_chain_cs_blocks.h"
-
-typedef struct dap_chain_block_chunk dap_chain_block_chunk_t;
-typedef struct dap_chain_block_cache_hash{
-    dap_chain_block_chunk_t * chunk;
-    dap_chain_block_cache_t *block_cache;
-    time_t ts_created;
-    dap_chain_hash_fast_t block_hash;
-    UT_hash_handle hh;
-} dap_chain_block_cache_hash_t;
-
-
-typedef struct dap_chain_block_chunk{
-    dap_chain_hash_fast_t chunk_id;
-    dap_chain_block_cache_hash_t *block_cache_hash;
-    dap_chain_block_cache_t *block_cache_top;
-    struct dap_chain_block_chunk * prev;
-    struct dap_chain_block_chunk * next;
-} dap_chain_block_chunk_t;
-
-
-typedef struct dap_chain_block_chunks{
-    dap_chain_cs_blocks_t * blocks;
-
-    dap_chain_block_cache_t *cache;
-
-    dap_chain_block_chunk_t * chunks_last;
-    dap_chain_block_chunk_t * chunks_first;
-    char * gdb_group;
-} dap_chain_block_chunks_t;
-
-dap_chain_block_chunks_t * dap_chain_block_chunks_create(dap_chain_cs_blocks_t * a_blocks);
-
-dap_chain_block_chunk_t * dap_chain_block_chunk_create(dap_chain_block_chunks_t * a_chunks);
-void dap_chain_block_chunk_delete( dap_chain_block_chunk_t * a_chunk);
-
-void dap_chain_block_chunks_delete(dap_chain_block_chunks_t * a_chunks);
-void dap_chain_block_chunks_sort(dap_chain_block_chunks_t * a_chunks);
-
-void dap_chain_block_chunks_add(dap_chain_block_chunks_t * a_chunks, dap_chain_block_cache_t  * a_block_cache);
-
-/**
- * @brief dap_chain_block_chunks_get_longest_count
- * @param a_chunks
- */
-static inline size_t dap_chain_block_chunks_get_longest_count(dap_chain_block_chunks_t * a_chunks)
-{
-    assert(a_chunks);
-    return a_chunks->chunks_last? HASH_COUNT(a_chunks->chunks_last->block_cache_hash):0;
-}
-
-/**
- * @brief dap_chain_block_chunks_get_longest_top
- * @param a_chunks
- * @return
- */
-static inline dap_chain_block_cache_t* dap_chain_block_chunks_get_longest_top(dap_chain_block_chunks_t * a_chunks)
-{
-    assert(a_chunks);
-    return a_chunks->chunks_last?a_chunks->chunks_last->block_cache_top:NULL;
-}
diff --git a/modules/type/blocks/include/dap_chain_cs_blocks.h b/modules/type/blocks/include/dap_chain_cs_blocks.h
index 1cdca941d391f12feb731287fd526a73037b332d..69a25180ca834f2d526d4c402d0445f58b0d1f42 100644
--- a/modules/type/blocks/include/dap_chain_cs_blocks.h
+++ b/modules/type/blocks/include/dap_chain_cs_blocks.h
@@ -40,7 +40,7 @@ typedef struct dap_chain_cs_blocks dap_chain_cs_blocks_t;
 
 typedef void (*dap_chain_cs_blocks_callback_t)(dap_chain_cs_blocks_t *);
 typedef void (*dap_chain_cs_blocks_callback_op_results_t)(dap_chain_cs_blocks_t * a_cs_blocks, int a_rc, void * a_arg);
-typedef int (*dap_chain_cs_blocks_callback_block_t)(dap_chain_cs_blocks_t *, dap_chain_block_t *, size_t);
+typedef int (*dap_chain_cs_blocks_callback_block_verify_t)(dap_chain_cs_blocks_t *a_cs_blocks, dap_chain_block_t *a_block, dap_hash_fast_t *a_block_hash, size_t a_block_size);
 typedef size_t (*dap_chain_cs_blocks_callback_block_sign_t)(dap_chain_cs_blocks_t *, dap_chain_block_t **, size_t);
 typedef dap_chain_block_t *(*dap_chain_cs_block_move_t)(dap_chain_cs_blocks_t *, size_t *);
 typedef dap_chain_block_t * (*dap_chain_cs_blocks_callback_block_create_t)(dap_chain_cs_blocks_t *,
@@ -56,7 +56,7 @@ typedef struct dap_chain_cs_blocks
 
    dap_chain_cs_blocks_callback_t callback_delete;
    dap_chain_cs_blocks_callback_block_create_t callback_block_create;
-   dap_chain_cs_blocks_callback_block_t callback_block_verify;
+   dap_chain_cs_blocks_callback_block_verify_t callback_block_verify;
    dap_chain_cs_blocks_callback_block_sign_t callback_block_sign;
    dap_chain_cs_block_move_t callback_new_block_move;
 
diff --git a/modules/type/blocks/tests/dap_chain_blocks_test.c b/modules/type/blocks/tests/dap_chain_blocks_test.c
index 1faa1f2e7e92ab83b2d12f607809b0ec39cd3617..74d87da324abff28757fea8a729b4ed5cae6c7a4 100644
--- a/modules/type/blocks/tests/dap_chain_blocks_test.c
+++ b/modules/type/blocks/tests/dap_chain_blocks_test.c
@@ -35,9 +35,10 @@ bool dap_chain_block_test_compare_chain_hash_lists(dap_chain_t* a_chain, dap_lis
     dap_list_t *l_branch_temp = NULL;
     dap_chain_atom_ptr_t l_atom = a_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_FIRST, &l_atom_size_from_iter);
     for (dap_list_t *l_branch_temp = a_atoms_hash_list; l_branch_temp && l_atom; 
-        l_branch_temp = l_branch_temp->next, l_atom = a_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_NEXT, &l_atom_size_from_iter)){
-        dap_test_msg("Check block %s : num %" DAP_UINT64_FORMAT_U " and %s", dap_chain_hash_fast_to_str_static(l_iter->cur_hash), l_iter->cur_num,
-                                            dap_chain_hash_fast_to_str_static((dap_hash_fast_t*)l_branch_temp->data));
+        l_branch_temp = l_branch_temp->next, l_atom = a_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_NEXT, &l_atom_size_from_iter)) {
+        char l_branch_hash_str[DAP_HASH_FAST_STR_SIZE];
+        dap_hash_fast_to_str((dap_hash_fast_t *)l_branch_temp->data, l_branch_hash_str, DAP_HASH_FAST_STR_SIZE);
+        dap_test_msg("Check block %s : num %" DAP_UINT64_FORMAT_U " and %s", dap_chain_hash_fast_to_str_static(l_iter->cur_hash), l_iter->cur_num, l_branch_hash_str);
         if (!dap_hash_fast_compare(l_iter->cur_hash, (dap_hash_fast_t*)l_branch_temp->data)){
             a_chain->callback_atom_iter_delete(l_iter);
             return false;
diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c
index a12a7f690a4022bc30e5fed7ae6839d16f3343e0..c6612bca4e2cdb3ef587c681c4b60544189c6e68 100644
--- a/modules/type/dag/dap_chain_cs_dag.c
+++ b/modules/type/dag/dap_chain_cs_dag.c
@@ -367,7 +367,6 @@ static void s_dap_chain_cs_dag_purge(dap_chain_t *a_chain)
     }
     pthread_mutex_unlock(&l_dag_pvt->events_mutex);
     dap_chain_cell_delete_all(a_chain);
-    //dap_chain_cell_delete_all_and_free_file(a_chain);
 }
 
 /**