diff --git a/dap-sdk b/dap-sdk
index c2ffae04d9161d1c5fec16d0c71056f0ae2cb93c..61bd9f38eac8773f0decc482f5488a2b520fcfb4 160000
--- a/dap-sdk
+++ b/dap-sdk
@@ -1 +1 @@
-Subproject commit c2ffae04d9161d1c5fec16d0c71056f0ae2cb93c
+Subproject commit 61bd9f38eac8773f0decc482f5488a2b520fcfb4
diff --git a/modules/chain/dap_chain.c b/modules/chain/dap_chain.c
index b587d7d0da4eaf5618905b63a0b08b123a3a5ac8..86d1935c47c392c49944c0dc8fc6d2a0808ffb1f 100644
--- a/modules/chain/dap_chain.c
+++ b/modules/chain/dap_chain.c
@@ -101,45 +101,38 @@ void dap_chain_deinit(void)
  */
 dap_chain_t *dap_chain_create(const char *a_chain_net_name, const char *a_chain_name, dap_chain_net_id_t a_chain_net_id, dap_chain_id_t a_chain_id)
 {
-    dap_chain_t *l_ret = DAP_NEW_Z(dap_chain_t);
+    dap_chain_item_t *l_chain_item = NULL;
+    dap_chain_item_id_t l_id = { a_chain_id, a_chain_net_id };
+    pthread_rwlock_wrlock(&s_chain_items_rwlock);
+    HASH_FIND(hh, s_chain_items, &l_id, sizeof(dap_chain_item_id_t), l_chain_item);
+    if (l_chain_item) {
+        log_it(L_ERROR, "Chain id %"DAP_UINT64_FORMAT_U" in net %"DAP_UINT64_FORMAT_U" already exists",
+                        a_chain_id.uint64, a_chain_net_id.uint64);
+        return pthread_rwlock_unlock(&s_chain_items_rwlock), NULL;
+    }
+    dap_chain_t *l_ret = DAP_NEW(dap_chain_t);
     if ( !l_ret ) {
         log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-        return NULL;   
+        return pthread_rwlock_unlock(&s_chain_items_rwlock), NULL;   
     }
     *l_ret = (dap_chain_t) {
-            .rwlock     = PTHREAD_RWLOCK_INITIALIZER,
-            .id         = a_chain_id,
-            .net_id     = a_chain_net_id,
-            .name       = dap_strdup(a_chain_name),
-            .net_name   = dap_strdup(a_chain_net_name),
-            .is_mapped  = dap_config_get_item_bool_default(g_config, "ledger", "mapped", true),
-            .cell_rwlock    = PTHREAD_RWLOCK_INITIALIZER,
-            .atom_notifiers = NULL
+        .rwlock     = PTHREAD_RWLOCK_INITIALIZER,
+        .id         = a_chain_id,
+        .net_id     = a_chain_net_id,
+        .name       = dap_strdup(a_chain_name),
+        .net_name   = dap_strdup(a_chain_net_name),
+        .is_mapped  = dap_config_get_item_bool_default(g_config, "ledger", "mapped", true),
+        .cell_rwlock= PTHREAD_RWLOCK_INITIALIZER,
+        ._pvt       = DAP_NEW_Z(dap_chain_pvt_t)
     };
-    dap_chain_pvt_t *l_chain_pvt = DAP_NEW_Z(dap_chain_pvt_t);
-    if (!l_chain_pvt) {
-        DAP_DEL_Z(l_ret->name);
-        DAP_DEL_Z(l_ret->net_name);
-        DAP_DELETE(l_ret);
-        log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-        return NULL;
-    }
-    l_ret->_pvt = l_chain_pvt;
-    dap_chain_item_t *l_ret_item = DAP_NEW_Z(dap_chain_item_t);
-    if (!l_ret_item) {
-        DAP_DEL_Z(l_ret->name);
-        DAP_DEL_Z(l_ret->net_name);
-        DAP_DELETE(l_ret->_pvt);
-        DAP_DELETE(l_ret);
-        log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-        return NULL;
-    }
-    *l_ret_item = (dap_chain_item_t) {
-            .item_id    = { a_chain_id, a_chain_net_id },
-            .chain      = l_ret
+    
+    l_chain_item = DAP_NEW(dap_chain_item_t);
+    *l_chain_item = (dap_chain_item_t) {
+        .item_id    = l_id,
+        .chain      = l_ret
     };
-    pthread_rwlock_wrlock(&s_chain_items_rwlock);
-    HASH_ADD(hh, s_chain_items, item_id, sizeof(dap_chain_item_id_t), l_ret_item);
+    
+    HASH_ADD(hh, s_chain_items, item_id, sizeof(dap_chain_item_id_t), l_chain_item);
     pthread_rwlock_unlock(&s_chain_items_rwlock);
     return l_ret;
 }
@@ -353,189 +346,107 @@ static bool s_datum_in_chain_types(uint16_t datum_type, dap_chain_type_t *chain_
  * @param a_chain_cfg_name chain config name, for example "network/home21-network/chain-0"
  * @return dap_chain_t* 
  */
-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)
+dap_chain_t *dap_chain_load_from_cfg(const char *a_chain_net_name, dap_chain_net_id_t a_chain_net_id, dap_config_t *a_cfg)
 {
-    log_it (L_DEBUG, "Loading chain from config \"%s\"", a_chain_cfg_name);
-
-    if (a_chain_net_name)
-	{
-        dap_config_t *l_cfg = dap_config_open(a_chain_cfg_name);
-        if (l_cfg)
-		{
-            dap_chain_t		*l_chain		= NULL;
-            dap_chain_id_t	l_chain_id		= {};
-            const char		*l_chain_id_str	= NULL;
-            const char 		*l_chain_name	= NULL;
-
-            // Recognize chains id
-            if ( (l_chain_id_str = dap_config_get_item_str(l_cfg,"chain","id")) != NULL ) {
-                if (dap_chain_id_parse(l_chain_id_str, &l_chain_id) != 0) {
-                    dap_config_close(l_cfg);
-                    return NULL;
-                }
-            } else {
-                log_it (L_ERROR, "Wasn't found chain id string in config");
-                dap_config_close(l_cfg);
-                return NULL;
-            }
-
-            log_it (L_NOTICE, "Chain id 0x%016"DAP_UINT64_FORMAT_x"  ( \"%s\" )", l_chain_id.uint64, l_chain_id_str);
-
-            // Read chain name
-            if ( ( l_chain_name = dap_config_get_item_str(l_cfg,"chain","name") ) == NULL )
-			{
-                log_it (L_ERROR,"Can't read chain net name %s", l_chain_id_str);
-                dap_config_close(l_cfg);
-                return NULL;
-            }
-
-            l_chain =  dap_chain_create(a_chain_net_name, l_chain_name, a_chain_net_id, l_chain_id);
-            if ( dap_chain_cs_create(l_chain, l_cfg) == 0 ) {
-
-                log_it (L_NOTICE, "Consensus initialized for chain id 0x%016"DAP_UINT64_FORMAT_x, l_chain_id.uint64);
-
-                if ( dap_config_get_item_str_default(l_cfg, "files","storage_dir", NULL) )
-				{
-                    DAP_CHAIN_PVT(l_chain)->file_storage_dir = (char*)dap_config_get_item_path( l_cfg, "files", "storage_dir" );
-                    if (!dap_dir_test(DAP_CHAIN_PVT(l_chain)->file_storage_dir)) {
-                        dap_mkdir_with_parents(DAP_CHAIN_PVT(l_chain)->file_storage_dir);
-                    }
-                } else
-                    log_it (L_INFO, "Not set file storage path, will not stored in files");
+    if (!a_chain_net_name || !a_cfg)
+        return NULL;
+    dap_chain_id_t l_chain_id = { }; 
+    const char *l_chain_name    = dap_config_get_item_str(a_cfg, "chain", "name"),
+               *l_chain_id_str  = dap_config_get_item_str(a_cfg, "chain", "id");
+    if (!l_chain_name || !l_chain_id_str || dap_chain_id_parse(l_chain_id_str, &l_chain_id) )
+        return log_it(L_ERROR, "Invalid chain name and/or id, fix \"%s\"", a_cfg->path), NULL;
+
+    log_it (L_INFO, "Loading chain %s, id 0x%016"DAP_UINT64_FORMAT_x": \"%s\" for net \"%s\" from config \"%s\"",
+                    l_chain_name, l_chain_id.uint64, l_chain_id_str, a_chain_net_name, a_cfg->path);
+
+    dap_chain_t *l_chain = dap_chain_create(a_chain_net_name, l_chain_name, a_chain_net_id, l_chain_id);
+    if (!l_chain)
+        return log_it(L_ERROR, "Can't create this chain!"), NULL;
+    if ( dap_chain_cs_create(l_chain, a_cfg) )
+        return log_it (L_ERROR, "Can't init consensus \"%s\" for chain \"%s\"",
+                                dap_config_get_item_str_default(a_cfg, "chain", "consensus", "<unknown>"), l_chain_name),
+            dap_chain_delete(l_chain), NULL;
+
+    log_it (L_INFO, "Consensus %s initialized for chain id 0x%016"DAP_UINT64_FORMAT_x,
+                    dap_config_get_item_str(a_cfg, "chain", "consensus"), l_chain_id.uint64);
+
+    if ( dap_config_get_item_str_default(a_cfg, "files", "storage_dir", NULL) )
+    {
+        DAP_CHAIN_PVT(l_chain)->file_storage_dir = dap_config_get_item_path( a_cfg, "files", "storage_dir" );
+        if (!dap_dir_test(DAP_CHAIN_PVT(l_chain)->file_storage_dir))
+            dap_mkdir_with_parents(DAP_CHAIN_PVT(l_chain)->file_storage_dir);
+    } else
+        log_it (L_INFO, "Not set file storage path, will not stored in files");
+
+    if (!l_chain->cells)
+        dap_chain_cell_create_fill( l_chain, (dap_chain_cell_id_t){ .uint64 = 0 } );
+    l_chain->config = a_cfg;
+    l_chain->load_priority = dap_config_get_item_uint16_default(a_cfg, "chain", "load_priority", 100);
+
+    uint16_t l_datum_types_count = 0, l_default_datum_types_count = 0, i, j;
+    const char  **l_datum_types = dap_config_get_array_str(a_cfg, "chain", "datum_types", &l_datum_types_count),
+                **l_default_datum_types = dap_config_get_array_str(a_cfg, "chain", "default_datum_types", &l_default_datum_types_count);
+
+    if ( l_datum_types && l_datum_types_count )
+    {
+        l_chain->datum_types = DAP_NEW_Z_COUNT(dap_chain_type_t, l_datum_types_count);
+        if ( !l_chain->datum_types )
+            return log_it(L_CRITICAL, "%s", c_error_memory_alloc), dap_chain_delete(l_chain), NULL;
+
+        for (i = 0; i < l_datum_types_count; i++)
+        {
+            dap_chain_type_t l_chain_type = s_chain_type_from_str(l_datum_types[i]);
+            if (l_chain_type != CHAIN_TYPE_INVALID)
+                l_chain->datum_types[l_chain->datum_types_count++] = l_chain_type;
+        }
+    } else
+        log_it(L_WARNING, "Can't read chain datum types for chain %s", l_chain_id_str);
 
-                if (!l_chain->cells)
-				{
-                    dap_chain_cell_id_t l_cell_id = {.uint64 = 0};
-                    dap_chain_cell_create_fill(l_chain, l_cell_id);
-                }
-            } else {
-                log_it (L_ERROR, "Can't init consensus \"%s\"",dap_config_get_item_str_default( l_cfg , "chain","consensus","NULL"));
-                dap_chain_delete(l_chain);
-                l_chain = NULL;
+    // add default datum types present
+    if ( l_default_datum_types && l_default_datum_types_count )
+    {
+        l_chain->default_datum_types = DAP_NEW_Z_COUNT(dap_chain_type_t, l_default_datum_types_count);
+        if ( !l_chain->default_datum_types ) {
+            DAP_DELETE(l_chain->datum_types);
+            return log_it(L_CRITICAL, "%s", c_error_memory_alloc), dap_chain_delete(l_chain), NULL;
+        }
+        for (i = 0; i < l_default_datum_types_count; i++)
+        {
+            dap_chain_type_t l_chain_type = s_chain_type_from_str(l_default_datum_types[i]);
+            if (l_chain_type != CHAIN_TYPE_INVALID
+            && s_chain_in_chain_types(l_chain_type, l_chain->datum_types, l_chain->datum_types_count))// <<--- check this chain_type in readed datum_types
+                l_chain->default_datum_types[l_chain->default_datum_types_count++] = l_chain_type;
+        }
+    } else
+        log_it(L_WARNING, "Can't read chain default datum types for chain %s", l_chain_id_str);
+        
+    l_datum_types = dap_config_get_array_str(a_cfg, "chain", "mempool_auto_types", &l_datum_types_count);
+    // add datum types for autoproc
+    if (l_datum_types && l_datum_types_count)
+    {
+        l_chain->autoproc_datum_types = DAP_NEW_Z_COUNT(uint16_t, l_chain->datum_types_count);
+        if ( !l_chain->autoproc_datum_types ) {
+            DAP_DELETE(l_chain->datum_types);
+            DAP_DELETE(l_chain->default_datum_types);
+            return log_it(L_CRITICAL, "%s", c_error_memory_alloc), dap_chain_delete(l_chain), NULL;
+        }
+        for (i = 0; i < l_datum_types_count; i++)
+        {
+            if (!dap_strcmp(l_datum_types[i], "all") && l_chain->datum_types_count)
+            {
+                for (j = 0; j < l_chain->datum_types_count; j++)
+                    l_chain->autoproc_datum_types[j] = s_chain_type_convert(l_chain->datum_types[j]);
+                l_chain->autoproc_datum_types_count = l_chain->datum_types_count;
+                break;
             }
-
-            if (l_chain)
-			{
-				// load priority for chain
-				l_chain->load_priority = dap_config_get_item_uint16_default(l_cfg, "chain", "load_priority", 100);
-
-                const char  **l_datum_types             = NULL;
-                const char  **l_default_datum_types     = NULL;
-                uint16_t    l_datum_types_count         = 0;
-                uint16_t    l_default_datum_types_count = 0;
-                uint16_t    l_count_recognized          = 0;
-
-				//		l_datum_types			=	(read chain datum types)
-				//	||	l_default_datum_types	=	(read chain default datum types if datum types readed and if present default datum types)
-
-				if (	(l_datum_types			= dap_config_get_array_str(l_cfg, "chain", "datum_types", &l_datum_types_count)) 					== NULL
-				||		(l_default_datum_types	= dap_config_get_array_str(l_cfg, "chain", "default_datum_types", &l_default_datum_types_count))	== NULL )
-				{
-					if (!l_datum_types)
-						log_it(L_WARNING, "Can't read chain datum types for chain %s", l_chain_id_str);
-					else
-						log_it(L_WARNING, "Can't read chain DEFAULT datum types for chain %s", l_chain_id_str);
-					//dap_config_close(l_cfg);
-					//return NULL;
-				}
-
-				// add datum types
-                if (l_datum_types && l_datum_types_count > 0)
-				{
-					l_chain->datum_types = DAP_NEW_SIZE(dap_chain_type_t, l_datum_types_count * sizeof(dap_chain_type_t)); // TODO: pls check counter for recognized types before memory allocation!
-                    if ( !l_chain->datum_types ) {
-                        DAP_DELETE(l_chain);
-                        log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                        return NULL;
-                    }
-                    l_count_recognized = 0;
-					for (uint16_t i = 0; i < l_datum_types_count; i++)
-					{
-						dap_chain_type_t l_chain_type = s_chain_type_from_str(l_datum_types[i]);
-						if (l_chain_type != CHAIN_TYPE_INVALID)
-						{
-							l_chain->datum_types[l_count_recognized] = l_chain_type;
-							l_count_recognized++;
-						}
-					}
-					l_chain->datum_types_count = l_count_recognized;
-				} else
-					l_chain->datum_types_count = 0;
-
-				// add default datum types present
-				if (l_default_datum_types && l_default_datum_types_count > 0)
-				{
-					l_chain->default_datum_types = DAP_NEW_SIZE(dap_chain_type_t, l_default_datum_types_count * sizeof(dap_chain_type_t)); // TODO: pls check counter for recognized types before memory allocation!
-                    if ( !l_chain->default_datum_types ) {
-                        if (l_chain->datum_types)
-                            DAP_DELETE(l_chain->datum_types);
-                        DAP_DELETE(l_chain);
-                        log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                        return NULL;
-                    }
-                    l_count_recognized = 0;
-					for (uint16_t i = 0; i < l_default_datum_types_count; i++)
-					{
-						dap_chain_type_t l_chain_type = s_chain_type_from_str(l_default_datum_types[i]);
-						if (l_chain_type != CHAIN_TYPE_INVALID
-						&& s_chain_in_chain_types(l_chain_type, l_chain->datum_types, l_chain->datum_types_count))// <<--- check this chain_type in readed datum_types
-						{
-							l_chain->default_datum_types[l_count_recognized] = l_chain_type;
-							l_count_recognized++;
-						}
-					}
-					l_chain->default_datum_types_count = l_count_recognized;
-				} else
-					l_chain->default_datum_types_count = 0;
-
-				if ((l_datum_types = dap_config_get_array_str(l_cfg, "chain", "mempool_auto_types", &l_datum_types_count)) == NULL)
-					log_it(L_WARNING, "Can't read chain mempool auto types for chain %s", l_chain_id_str);
-
-				// add datum types for autoproc
-				if (l_datum_types && l_datum_types_count)
-				{
-					l_chain->autoproc_datum_types = DAP_NEW_Z_SIZE(uint16_t, l_chain->datum_types_count * sizeof(uint16_t)); // TODO: pls check counter for recognized types before memory allocation!
-                    if ( !l_chain->autoproc_datum_types ) {
-                        log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                        if (l_chain->datum_types)
-                            DAP_DELETE(l_chain->datum_types);
-                        if (l_chain->default_datum_types)
-                            DAP_DELETE(l_chain->default_datum_types);
-                        DAP_DELETE(l_chain);
-                        return NULL;
-                    }
-                    l_count_recognized = 0;
-					for (uint16_t i = 0; i < l_datum_types_count; i++)
-					{
-						if (!dap_strcmp(l_datum_types[i], "all") && l_chain->datum_types_count)
-						{
-							for (int j = 0; j < l_chain->datum_types_count; j++)
-								l_chain->autoproc_datum_types[j] = s_chain_type_convert(l_chain->datum_types[j]);
-							l_count_recognized = l_chain->datum_types_count;
-							break;
-						}
-						uint16_t l_chain_type = s_datum_type_from_str(l_datum_types[i]);
-						if (l_chain_type != DAP_CHAIN_DATUM_CUSTOM
-						&&	s_datum_in_chain_types(l_chain_type, l_chain->datum_types, l_chain->datum_types_count))// <<--- check this chain_datum_type in readed datum_types
-						{
-							l_chain->autoproc_datum_types[l_count_recognized] = l_chain_type;
-							l_count_recognized++;
-						}
-					}
-					l_chain->autoproc_datum_types_count = l_count_recognized;
-				} else
-					l_chain->autoproc_datum_types_count = 0;
-			}
-            if (l_chain)
-                l_chain->config = l_cfg;
-            return l_chain;
-        } else
-            return NULL;
-
-    } else {
-        log_it (L_WARNING, "NULL net_id string");
-        return NULL;
-    }
+            uint16_t l_chain_type = s_datum_type_from_str(l_datum_types[i]);
+            if (l_chain_type != DAP_CHAIN_DATUM_CUSTOM
+            &&	s_datum_in_chain_types(l_chain_type, l_chain->datum_types, l_chain->datum_types_count))// <<--- check this chain_datum_type in readed datum_types
+                l_chain->autoproc_datum_types[l_chain->autoproc_datum_types_count++] = l_chain_type;
+        }
+    } else
+        log_it(L_WARNING, "Can't read chain mempool auto types for chain %s", l_chain_id_str);
+    return l_chain;
 }
 
 
diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h
index e8e027832c506591033c6de38a4734f08515b731..f59f10a6367fe6975a46a575e2b2b9a2f6d3f070 100644
--- a/modules/chain/include/dap_chain.h
+++ b/modules/chain/include/dap_chain.h
@@ -139,7 +139,8 @@ typedef enum dap_chain_type {
     CHAIN_TYPE_CA = 4,
     CHAIN_TYPE_SIGNER = 5,
     CHAIN_TYPE_DECREE = 7,
-    CHAIN_TYPE_ANCHOR = 8
+    CHAIN_TYPE_ANCHOR = 8,
+    CHAIN_TYPE_MAX
 } dap_chain_type_t;
 
 // not rotate, use in state machine
@@ -243,12 +244,8 @@ typedef struct dap_chain_atom_notifier {
 } dap_chain_atom_notifier_t;
 
 typedef struct dap_chain_pvt {
-    dap_chain_t * chain;
-    char * file_storage_dir;
-    char * cs_name;
-    bool cs_started;
-    int celled;
-    bool need_reorder;
+    char *cs_name, *file_storage_dir;
+    bool cs_started, need_reorder;
 } dap_chain_pvt_t;
 
 #define DAP_CHAIN_PVT(a) ((dap_chain_pvt_t *)a->_pvt)
@@ -277,7 +274,7 @@ bool dap_chain_has_file_store(dap_chain_t * a_chain);
 void dap_chain_info_dump_log(dap_chain_t * a_chain);
 
 dap_chain_t * dap_chain_find_by_id(dap_chain_net_id_t a_chain_net_id,dap_chain_id_t a_chain_id);
-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);
+dap_chain_t *dap_chain_load_from_cfg(const char *a_chain_net_name, dap_chain_net_id_t a_chain_net_id, dap_config_t *a_cfg);
 
 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, dap_proc_thread_t *a_thread, void *a_arg);
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 e9eff2ad1bfca05fedcb5e31eec9a9d211a8d73d..34cb96015ab949f9e62df0f2b95e8803c323a46d 100644
--- a/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c
+++ b/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c
@@ -96,6 +96,8 @@ static int s_cli_dag_poa(int argc, char ** argv, void **a_str_reply);
 static bool s_seed_mode = false;
 static bool s_debug_more = false;
 
+#define DAG_ROUND_NEW_TTL 3600 // 1 hour
+
 /**
  * @brief
  * init consensus dag_poa
@@ -698,7 +700,7 @@ static int s_callback_created(dap_chain_t * a_chain, dap_config_t *a_chain_net_c
     assert(l_net);
     dap_global_db_cluster_t *l_dag_cluster = dap_global_db_cluster_add(dap_global_db_instance_get_default(), NULL,
                                                                        dap_guuid_compose(l_net->pub.id.uint64, DAP_CHAIN_CLUSTER_ID_DAG),
-                                                                       l_dag->gdb_group_events_round_new, 1, true,
+                                                                       l_dag->gdb_group_events_round_new, DAG_ROUND_NEW_TTL, true,
                                                                        DAP_GDB_MEMBER_ROLE_NOBODY, DAP_CLUSTER_TYPE_AUTONOMIC);
     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);
diff --git a/modules/consensus/esbocs/dap_chain_cs_esbocs.c b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
index 549de5d62917dc5b750ddfe4e2cd80a90c6cb4be..5adf7d6c33f70594a11e5edc6789301bdf0a2b1c 100644
--- a/modules/consensus/esbocs/dap_chain_cs_esbocs.c
+++ b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
@@ -50,6 +50,8 @@ enum s_esbocs_session_state {
     DAP_CHAIN_ESBOCS_SESSION_STATE_PREVIOUS     // fictive sate to change back
 };
 
+#define ESBOCS_PENALTY_TTL ( 72 * 3600 ) // 3 days
+
 static dap_list_t *s_validator_check(dap_chain_addr_t *a_addr, dap_list_t *a_validators);
 static void s_session_proc_state(void *a_arg);
 static void s_session_state_change(dap_chain_esbocs_session_t *a_session, enum s_esbocs_session_state a_new_state, dap_time_t a_time);
@@ -539,7 +541,7 @@ static int s_callback_created(dap_chain_t *a_chain, dap_config_t *a_chain_net_cf
     char *l_sync_group = s_get_penalty_group(l_net->pub.id);
     l_session->db_cluster = dap_global_db_cluster_add(dap_global_db_instance_get_default(), NULL,
                                                       dap_guuid_compose(l_net->pub.id.uint64, DAP_CHAIN_CLUSTER_ID_ESBOCS),
-                                                      l_sync_group, 72, true,
+                                                      l_sync_group, ESBOCS_PENALTY_TTL, true,
                                                       DAP_GDB_MEMBER_ROLE_NOBODY, DAP_CLUSTER_TYPE_AUTONOMIC);
     dap_link_manager_add_net_associate(l_net->pub.id.uint64, l_session->db_cluster->links_cluster);
     dap_global_db_erase_table_sync(l_sync_group);     // Drop table on stratup
@@ -729,13 +731,13 @@ int dap_chain_esbocs_set_min_validators_count(dap_chain_t *a_chain, uint16_t a_n
     return 0;
 }
 
-int dap_chain_esbocs_get_min_validators_count(dap_chain_net_id_t a_net_id)
+uint16_t dap_chain_esbocs_get_min_validators_count(dap_chain_net_id_t a_net_id)
 {
     dap_chain_esbocs_session_t *l_session;
     DL_FOREACH(s_session_items, l_session)
         if (l_session->chain->net_id.uint64 == a_net_id.uint64)
             return PVT(l_session->esbocs)->min_validators_count;
-    return -1;
+    return 0;
 }
 
 int dap_chain_esbocs_set_signs_struct_check(dap_chain_t *a_chain, bool a_enable)
diff --git a/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h b/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h
index e097d109a6114acb9a7e01ea5c6dc99e3323d675..7a43019bf392d48c71f49cfb3768ade7a3c48360 100644
--- a/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h
+++ b/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h
@@ -268,6 +268,6 @@ bool dap_chain_esbocs_remove_validator_from_clusters(dap_chain_net_id_t a_net_id
 uint256_t dap_chain_esbocs_get_collecting_level(dap_chain_t *a_chain);
 dap_enc_key_t *dap_chain_esbocs_get_sign_key(dap_chain_t *a_chain);
 int dap_chain_esbocs_set_min_validators_count(dap_chain_t *a_chain, uint16_t a_new_value);
-int dap_chain_esbocs_get_min_validators_count(dap_chain_net_id_t a_net_id);
+uint16_t dap_chain_esbocs_get_min_validators_count(dap_chain_net_id_t a_net_id);
 int dap_chain_esbocs_set_emergency_validator(dap_chain_t *a_chain, bool a_add, uint32_t a_sign_type, dap_hash_fast_t *a_validator_hash);
 int dap_chain_esbocs_set_signs_struct_check(dap_chain_t *a_chain, bool a_enable);
diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c
index 0089c55664825239f888c5eb054b554ecd4e5e76..144b69959c5047e5a094f0ae115207ce73ad769b 100644
--- a/modules/net/dap_chain_ledger.c
+++ b/modules/net/dap_chain_ledger.c
@@ -2585,42 +2585,23 @@ dap_ledger_t *dap_ledger_create(dap_chain_net_t *a_net, uint16_t a_flags)
     pthread_mutex_init(&l_ledger_pvt->load_mutex, NULL);
 
 #ifndef DAP_LEDGER_TEST
-    char * l_chains_path = dap_strdup_printf("%s/network/%s", dap_config_path(), a_net->pub.name);
-    DIR * l_chains_dir = opendir(l_chains_path);
-    DAP_DEL_Z(l_chains_path);
-
-    struct dirent * l_dir_entry;
-    while ( (l_dir_entry = readdir(l_chains_dir) )!= NULL ){
-        if (l_dir_entry->d_name[0] == '\0')
-            continue;
-        char * l_entry_name = dap_strdup(l_dir_entry->d_name);
-        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.%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, 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, "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);
-            }
+    for ( dap_chain_t *l_chain = a_net->pub.chains; l_chain; l_chain = l_chain->next ) {
+        uint16_t l_whitelist_size, l_blacklist_size, i;
+        const char **l_whitelist = dap_config_get_array_str(l_chain->config, "ledger", "hard_accept_list", &l_whitelist_size),
+                   **l_blacklist = dap_config_get_array_str(l_chain->config, "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);
         }
-        DAP_DELETE (l_entry_name);
-    }
-    closedir(l_chains_dir);
+        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);
+        }
+        log_it(L_DEBUG, "Chain %s.%s has %d datums in HAL and %d datums in HRL", a_net->pub.name, l_chain->name, l_whitelist_size, l_blacklist_size);
 
+    }
     if ( l_ledger_pvt->cached )
         // load ledger cache from GDB
         dap_ledger_load_cache(l_ledger);
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index 82f48854cdce9b33fed857bf7e3f12cec7e6dd15..f96876ca0c123643f522706371c5c3aef96b8354 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -225,7 +225,7 @@ static bool s_net_states_proc(void *a_arg);
 static void s_net_states_notify(dap_chain_net_t * l_net);
 static void s_nodelist_change_notify(dap_store_obj_t *a_obj, void *a_arg);
 //static void s_net_proc_kill( dap_chain_net_t * a_net );
-static int s_net_init(const char * a_net_name, uint16_t a_acl_idx);
+static int s_net_init(const char *a_net_name, const char *a_path, uint16_t a_acl_idx);
 static bool s_net_load(void *a_arg);
 static int s_net_try_online(dap_chain_net_t *a_net);
 static int s_cli_net(int argc, char ** argv, void **a_str_reply);
@@ -276,41 +276,36 @@ int dap_chain_net_init()
             "\tPrint list of PoA cerificates for this network\n");
 
     s_debug_more = dap_config_get_item_bool_default(g_config,"chain_net","debug_more", s_debug_more);
-
-    char * l_net_dir_str = dap_strdup_printf("%s/network", dap_config_path());
-    DIR * l_net_dir = opendir( l_net_dir_str);
-    if ( l_net_dir ){
-        struct dirent * l_dir_entry = NULL;
+    char l_path[MAX_PATH + 1] = { '\0' }, *l_end = NULL;
+    int l_pos = snprintf(l_path, MAX_PATH, "%s/network/", dap_config_path());
+    if (l_pos >= MAX_PATH - 4)
+        return log_it(L_ERROR, "Invalid path to net configs, fix it!"), -1;
+    DIR *l_dir = opendir(l_path);
+    if ( l_dir ){
+        struct dirent *l_dir_entry = NULL;
         uint16_t l_acl_idx = 0;
-        while ( (l_dir_entry = readdir(l_net_dir) ) ){
-            if (l_dir_entry->d_name[0]=='\0' || l_dir_entry->d_name[0]=='.')
+        while ( (l_dir_entry = readdir(l_dir)) ) {
+            if (*l_dir_entry->d_name =='\0' || *l_dir_entry->d_name =='.')
                 continue;
             // don't search in directories
-            char l_full_path[MAX_PATH + 1] = {0};
-            snprintf(l_full_path, sizeof(l_full_path), "%s/%s", l_net_dir_str, l_dir_entry->d_name);
-            if(dap_dir_test(l_full_path)) {
+            l_end = dap_strncpy(l_path + l_pos, l_dir_entry->d_name, MAX_PATH - l_pos);
+            if ( dap_dir_test(l_path) )
                 continue;
-            }
             // search only ".cfg" files
-            if(strlen(l_dir_entry->d_name) > 4) { // It has non zero name excluding file extension
-                if( strncmp(l_dir_entry->d_name + strlen(l_dir_entry->d_name) - 4, ".cfg", 4) ) {
-                    // its not .cfg file
-                    continue;
-                }
+            if ( (int)(l_end - l_path) + l_pos > 4 && strncmp(l_end - 4, ".cfg", 4) )
+                continue;
+            
+            log_it(L_DEBUG, "Loading net config \"%s\"", l_dir_entry->d_name);
+            *(l_end - 4) = '\0';
+            if ( !dap_dir_test(l_path) ) {
+                log_it(L_ERROR, "Path \"%s\" not found, skipping it", l_path);
+                continue;
             }
-            log_it(L_DEBUG,"Network config %s try to load", l_dir_entry->d_name);
-            //char* l_dot_pos = rindex(l_dir_entry->d_name,'.');
-            char* l_dot_pos = strchr(l_dir_entry->d_name,'.');
-            if ( l_dot_pos )
-                *l_dot_pos = '\0';
-            s_net_init(l_dir_entry->d_name, l_acl_idx++);
+            s_net_init(l_path + l_pos, l_path, l_acl_idx++);
         }
-        closedir(l_net_dir);
-    } else {
-        log_it(L_WARNING, "Can't open entries on path %s, error %d: \"%s\"",
-                           l_net_dir_str, errno, dap_strerror(errno));
-    }
-    DAP_DELETE (l_net_dir_str);
+        closedir(l_dir);
+    } else
+        log_it(L_WARNING, "Can't open entries on path %s, error %d: \"%s\"", l_path, errno, dap_strerror(errno));
 
     dap_enc_http_set_acl_callback(s_net_set_acl);
     log_it(L_NOTICE,"Chain networks initialized");
@@ -631,7 +626,7 @@ static void s_net_states_notify(dap_chain_net_t *a_net)
  */
 dap_chain_node_role_t dap_chain_net_get_role(dap_chain_net_t * a_net)
 {
-    return  PVT(a_net)->node_role;
+    return PVT(a_net)->node_role;
 }
 
 /**
@@ -1659,48 +1654,10 @@ static int s_cli_net(int argc, char **argv, void **reply)
     return  l_ret;
 }
 
-/**
- * @brief remove_duplicates_in_chain_by_priority
- * remove duplicates default datum types in chain by priority
- * @param *l_chain_1 chain 1
- * @param *l_chain_2 chain 2
- * @return void
- */
-
-static void remove_duplicates_in_chain_by_priority(dap_chain_t *l_chain_1, dap_chain_t *l_chain_2)
-{
-    dap_chain_t *l_chain_high_priority = (l_chain_1->load_priority > l_chain_2->load_priority) ? l_chain_2 : l_chain_1; //such distribution is made for correct operation with the same priority
-    dap_chain_t *l_chain_low_priority = (l_chain_1->load_priority > l_chain_2->load_priority) ? l_chain_1 : l_chain_2; //...^...^...^...
-
-    for (int i = 0; i < l_chain_high_priority->default_datum_types_count; i++)
-    {
-        for (int j = 0; j < l_chain_low_priority->default_datum_types_count; j++)
-        {
-            if (l_chain_high_priority->default_datum_types[i] == l_chain_low_priority->default_datum_types[j])
-            {
-                l_chain_low_priority->default_datum_types[j] = l_chain_low_priority->default_datum_types[l_chain_low_priority->default_datum_types_count - 1];
-                --l_chain_low_priority->default_datum_types_count;
-                --j;
-            }
-        }
-    }
-}
-
-// for sequential loading chains
-typedef struct list_priority_{
-    uint16_t prior;
-    char * chains_path;
-} list_priority;
-
-static int callback_compare_prioritity_list(dap_list_t *a_item1, dap_list_t *a_item2)
-{
-    list_priority   *l_item1 = a_item1->data,
-                    *l_item2 = a_item2->data;
-    if (!l_item1 || !l_item2) {
-        log_it(L_CRITICAL, "Invalid arg");
-        return 0;
-    }
-    return l_item1->prior == l_item2->prior ? 0 : l_item1->prior > l_item2->prior ? 1 : -1;
+static int s_cmp_cfg_pri(dap_config_t *cfg1, dap_config_t *cfg2) {
+    uint16_t l_pri1 = dap_config_get_item_uint16_default(cfg1, "chain", "load_priority", 100),
+             l_pri2 = dap_config_get_item_uint16_default(cfg2, "chain", "load_priority", 100);
+    return l_pri1 == l_pri2 ? 0 : l_pri1 > l_pri2 ? 1 : -1;
 }
 
 /**
@@ -1712,8 +1669,6 @@ void dap_chain_net_deinit()
     dap_chain_net_balancer_deinit();
     dap_chain_net_t *l_net, *l_tmp;
     HASH_ITER(hh2, s_nets_by_id, l_net, l_tmp) {
-        HASH_DEL(s_nets_by_name, l_net);
-        HASH_DELETE(hh2, s_nets_by_id, l_net);
         dap_chain_net_delete(l_net);
     }
     dap_http_ban_list_client_deinit();
@@ -1746,6 +1701,8 @@ void dap_chain_net_delete(dap_chain_net_t *a_net)
         dap_ledger_purge(a_net->pub.ledger, true);
         dap_ledger_handle_free(a_net->pub.ledger);
     }
+    HASH_DEL(s_nets_by_name, a_net);
+    HASH_DELETE(hh2, s_nets_by_id, a_net);
     DAP_DELETE(a_net);
 }
 
@@ -1773,15 +1730,12 @@ int dap_chain_net_test_init()
  * @param a_acl_idx currently 0
  * @return int
  */
-int s_net_init(const char *a_net_name, uint16_t a_acl_idx)
+int s_net_init(const char *a_net_name, const char *a_path, uint16_t a_acl_idx)
 {
-    dap_config_t *l_cfg = NULL;
-    {
-        char l_cfg_path[strlen(a_net_name) + sizeof("network/")];
-        dap_stpcpy(dap_stpcpy(l_cfg_path, "network/"), a_net_name);
-        if (!( l_cfg = dap_config_open(l_cfg_path) ))
-            return log_it(L_ERROR,"Can't open default network config %s", l_cfg_path), -1;
-    }
+    dap_config_t *l_cfg = dap_config_open(a_path);
+    if (!l_cfg)
+        return log_it(L_ERROR,"Can't open default network config %s", a_path), -1;
+
     dap_chain_net_t *l_net = s_net_new(a_net_name, l_cfg);
     if ( !l_net ) 
         return log_it(L_ERROR,"Can't create net \"%s\"", a_net_name), dap_config_close(l_cfg), -1;
@@ -1892,100 +1846,66 @@ int s_net_init(const char *a_net_name, uint16_t a_acl_idx)
                     e, i, a_net_name);
 
     /* *** Chains init by configs *** */
-    char * l_chains_path = dap_strdup_printf("%s/network/%s", dap_config_path(), l_net->pub.name);
-    DIR * l_chains_dir = opendir(l_chains_path);
-    DAP_DEL_Z(l_chains_path);
-    if (!l_chains_dir) {
-        log_it(L_ERROR, "Can't find any chains for network %s", l_net->pub.name);
-        dap_chain_net_delete(l_net);
-        return -7;
-    }
-    // for sequential loading chains
-    dap_list_t *l_prior_list = NULL;
-
-    struct dirent * l_dir_entry;
-    while ( (l_dir_entry = readdir(l_chains_dir) )!= NULL ){
-        if (l_dir_entry->d_name[0]=='\0')
-            continue;
-        char *l_entry_name = dap_strdup(l_dir_entry->d_name);
-        if (!l_entry_name) {
-            log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-            dap_chain_net_delete(l_net);
-            closedir(l_chains_dir);
-            return -8;
-        }
-        if (strlen (l_entry_name) > 4 ){ // It has non zero name excluding file extension
-            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);
-                l_chains_path = dap_strdup_printf("network/%s/%s",l_net->pub.name,l_entry_name);
-                dap_config_t * l_cfg_new = dap_config_open(l_chains_path);
-                if(l_cfg_new) {
-                    list_priority *l_chain_prior = DAP_NEW_Z(list_priority);
-                    if (!l_chain_prior) {
-                        log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                        DAP_DELETE(l_entry_name);
-                        dap_config_close(l_cfg_new);
-                        closedir(l_chains_dir);
-                        dap_chain_net_delete(l_net);
-                        return -9;
-                    }
-                    l_chain_prior->prior = dap_config_get_item_uint16_default(l_cfg_new, "chain", "load_priority", 100);
-                    log_it(L_DEBUG, "Chain priority: %u", l_chain_prior->prior);
-                    l_chain_prior->chains_path = l_chains_path;
-                    // add chain to load list;
-                    l_prior_list = dap_list_append(l_prior_list, l_chain_prior);
-                    dap_config_close(l_cfg_new);
-                }
+    DIR *l_chains_dir = opendir(a_path);
+    if (!l_chains_dir)
+        return log_it(L_ERROR, "Can't find any chains for network %s", l_net->pub.name), dap_chain_net_delete(l_net), -7;
+
+    struct dirent *l_dir_entry;
+    dap_config_t *l_chain_config, *l_all_chain_configs = NULL, *l_tmp_cfg;
+    char l_chain_cfg_path[MAX_PATH + 1] = { '\0' };
+    int l_pos = snprintf(l_chain_cfg_path, MAX_PATH, "network/%s/", a_net_name);
+    while (( l_dir_entry = readdir(l_chains_dir) )) {
+        unsigned short l_len = strlen(l_dir_entry->d_name);
+        if ( l_len > 4 && !dap_strncmp(l_dir_entry->d_name + l_len - 4, ".cfg", 4) ) {
+            *(l_dir_entry->d_name + l_len - 4) = '\0';
+            log_it(L_DEBUG, "Opening chain config \"%s.%s\"", a_net_name, l_dir_entry->d_name);
+            dap_strncpy(l_chain_cfg_path + l_pos, l_dir_entry->d_name, MAX_PATH - l_pos);
+            if (!( l_chain_config = dap_config_open(l_chain_cfg_path) )) {
+                log_it(L_ERROR, "Can't open chain config %s, skip it", l_dir_entry->d_name);
+                continue;
             }
+            HASH_ADD_KEYPTR(hh, l_all_chain_configs, l_chain_config->path, strlen(l_chain_config->path), l_chain_config);
         }
-        DAP_DELETE(l_entry_name);
     }
     closedir(l_chains_dir);
+    if (!l_all_chain_configs)
+        return log_it(L_ERROR, "Can't find any chains for network %s", l_net->pub.name), dap_chain_net_delete(l_net), -8;
 
-    // sort list with chains names by priority
-    l_prior_list = dap_list_sort(l_prior_list, callback_compare_prioritity_list);
-
-    // create and load chains params by priority
+    HASH_SORT(l_all_chain_configs, s_cmp_cfg_pri);
     dap_chain_t *l_chain;
-    dap_list_t *l_list = l_prior_list;
-    while(l_list){
-        list_priority *l_chain_prior = l_list->data;
-        // Create chain object
-        l_chain = dap_chain_load_from_cfg(l_net->pub.name, l_net->pub.id, l_chain_prior->chains_path);
-        if(l_chain)
+    dap_chain_type_t *l_types_arr;
+    char l_occupied_default_types[CHAIN_TYPE_MAX] = { 0 };
+    uint16_t k;
+    HASH_ITER(hh, l_all_chain_configs, l_chain_config, l_tmp_cfg) {
+        if (( l_chain = dap_chain_load_from_cfg(l_net->pub.name, l_net->pub.id, l_chain_config) )) {
             DL_APPEND(l_net->pub.chains, l_chain);
-        else
-            log_it(L_WARNING, "Can't process chain from config %s", l_chain_prior->chains_path);
-        DAP_DELETE (l_chain_prior->chains_path);
-        l_list = dap_list_next(l_list);
-    }
-    dap_list_free_full(l_prior_list, NULL);
-    dap_chain_t *l_chain02;
-    DL_FOREACH(l_net->pub.chains, l_chain){
-        DL_FOREACH(l_net->pub.chains, l_chain02){
-            if (l_chain != l_chain02){
-                if (l_chain->id.uint64 == l_chain02->id.uint64) {
-                    log_it(L_ERROR, "Your network %s has chains with duplicate ids: 0x%"DAP_UINT64_FORMAT_U", chain01: %s, chain02: %s", l_chain->net_name,
-                                    l_chain->id.uint64, l_chain->name,l_chain02->name);
-                    log_it(L_ERROR, "Please, fix your configs and restart node");
-                    return -10;
-                }
-                if (!dap_strcmp(l_chain->name, l_chain02->name)) {
-                    log_it(L_ERROR, "Your network %s has chains with duplicate names %s: chain01 id = 0x%"DAP_UINT64_FORMAT_U", chain02 id = 0x%"DAP_UINT64_FORMAT_U"",l_chain->net_name,
-                           l_chain->name, l_chain->id.uint64, l_chain02->id.uint64);
-                    log_it(L_ERROR, "Please, fix your configs and restart node");
-                    return -11;
-                }
-                remove_duplicates_in_chain_by_priority(l_chain, l_chain02);
+            l_types_arr = l_chain->default_datum_types;
+            for (i = 0, k = l_chain->default_datum_types_count; i < k; ++i) {
+                if ( l_occupied_default_types[l_types_arr[i]] ) {
+                    if ( i < k - 1 )
+                        l_types_arr[i] =
+                            l_types_arr[k - 1];
+                    --i;
+                    --k;
+                } else
+                    l_occupied_default_types[l_types_arr[i]] = 1;
+            }
+            if ( k < l_chain->default_datum_types_count ) {
+                l_chain->default_datum_types_count = k;
+                l_chain->default_datum_types = DAP_REALLOC_COUNT(l_chain->default_datum_types, k);
             }
+        } else {
+            HASH_DEL(l_all_chain_configs, l_chain_config);
+            dap_config_close(l_chain_config);
         }
     }
+    HASH_CLEAR(hh, l_all_chain_configs);
     // LEDGER model
     uint16_t l_ledger_flags = 0;
     switch ( PVT( l_net )->node_role.enums ) {
     case NODE_ROLE_LIGHT:
-        break;
+        //break;
+        PVT( l_net )->node_role.enums = NODE_ROLE_FULL; // TODO: implement light mode
     case NODE_ROLE_FULL:
         l_ledger_flags |= DAP_LEDGER_CHECK_LOCAL_DS;
         if (dap_config_get_item_bool_default(g_config, "ledger", "cache_enabled", false))
@@ -2135,11 +2055,10 @@ bool s_net_load(void *a_arg)
         // Personal chain mempool cluster for each chain
         l_gdb_groups_mask = dap_strdup_printf("%s.chain-%s.mempool", l_net->pub.gdb_groups_prefix, l_chain->name);
         dap_global_db_cluster_t *l_cluster = dap_global_db_cluster_add(
-                                                    dap_global_db_instance_get_default(),
-                                                    l_net->pub.name, dap_guuid_compose(l_net->pub.id.uint64, 0),
-                                                    l_gdb_groups_mask, DAP_CHAIN_NET_MEMPOOL_TTL, true,
-                                                    DAP_GDB_MEMBER_ROLE_USER,
-                                                    DAP_CLUSTER_TYPE_EMBEDDED);
+                                                dap_global_db_instance_get_default(), l_net->pub.name, 
+                                                dap_guuid_compose(l_net->pub.id.uint64, 0), l_gdb_groups_mask, 
+                                                dap_config_get_item_int32_default(l_net->pub.config, "global_db", "mempool_ttl", DAP_CHAIN_NET_MEMPOOL_TTL),
+                                                true, DAP_GDB_MEMBER_ROLE_USER, DAP_CLUSTER_TYPE_EMBEDDED);
         if (!l_cluster) {
             log_it(L_ERROR, "Can't initialize mempool cluster for network %s", l_net->pub.name);
             l_err_code = -2;
@@ -2167,7 +2086,7 @@ bool s_net_load(void *a_arg)
     l_gdb_groups_mask = dap_strdup_printf("%s.orders", l_net->pub.gdb_groups_prefix);
     l_net_pvt->common_orders = dap_global_db_cluster_add(dap_global_db_instance_get_default(),
                                                           l_net->pub.name, dap_guuid_compose(l_net->pub.id.uint64, 0),
-                                                          l_gdb_groups_mask, 336, true,
+                                                          l_gdb_groups_mask, 0, true,
                                                           DAP_GDB_MEMBER_ROLE_USER,
                                                           DAP_CLUSTER_TYPE_EMBEDDED);
     if (!l_net_pvt->common_orders) {
@@ -2180,7 +2099,7 @@ bool s_net_load(void *a_arg)
     l_gdb_groups_mask = dap_strdup_printf("%s.nodes.states", l_net->pub.gdb_groups_prefix);
     l_net_pvt->nodes_states = dap_global_db_cluster_add(dap_global_db_instance_get_default(),
                                                         l_net->pub.name, dap_guuid_compose(l_net->pub.id.uint64, 0),
-                                                        l_gdb_groups_mask, 6, true,
+                                                        l_gdb_groups_mask, DAP_CHAIN_NET_NODES_TTL, true,
                                                         DAP_GDB_MEMBER_ROLE_USER,
                                                         DAP_CLUSTER_TYPE_EMBEDDED);
     DAP_DELETE(l_gdb_groups_mask);
diff --git a/modules/net/dap_chain_net_balancer.c b/modules/net/dap_chain_net_balancer.c
index 02dd26c1ad252ccc30f28083cc55c8505ee605c8..f99b135e6eee584d30bee16f07ac7b46aaac2588 100644
--- a/modules/net/dap_chain_net_balancer.c
+++ b/modules/net/dap_chain_net_balancer.c
@@ -509,6 +509,7 @@ void dap_chain_net_balancer_request(void *a_arg)
             DAP_DELETE(l_ignored_addrs);
         }
         // request prepare
+        const char *l_net_name = l_arg->net->pub.name, *l_bal_type = dap_chain_net_balancer_type_to_str(l_arg->type);
         char *l_request = dap_strdup_printf("%s/%s?version=%d,method=r,needlink=%d,net=%s,ignored=%s",
                                                 DAP_UPLINK_PATH_BALANCER,
                                                 DAP_BALANCER_URI_HASH,
@@ -516,14 +517,10 @@ void dap_chain_net_balancer_request(void *a_arg)
                                                 (int)l_required_links_count,
                                                 l_arg->net->pub.name,
                                                 l_ignored_addrs_str ? l_ignored_addrs_str : "");
-        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);
-        }
+        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", l_bal_type, l_net_name);
         DAP_DEL_MULTY(l_ignored_addrs_str, l_request);
     } else {
         l_arg->host_port = DNS_LISTEN_PORT;
diff --git a/modules/net/dap_chain_net_decree.c b/modules/net/dap_chain_net_decree.c
index 28fbef933c7df9828f47ba14f32b60fbf6cf9a01..4b1ace31457c4a4a22db34fa11fed03ccbb8f4fd 100644
--- a/modules/net/dap_chain_net_decree.c
+++ b/modules/net/dap_chain_net_decree.c
@@ -448,12 +448,12 @@ static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain
                 log_it(L_WARNING,"Can't get signing address from decree.");
                 return -105;
             }
-
-            uint16_t l_current_count = dap_chain_net_srv_stake_get_total_keys(a_net->pub.id, NULL);
+            if (!a_anchored)
+                break;
             uint16_t l_min_count = dap_chain_esbocs_get_min_validators_count(a_net->pub.id);
-            if (l_current_count == l_min_count) {
-                log_it(L_WARNING, "Can't invalidate validator cause min validators count %hu will become less than total count for net %s",
-                                                                                l_current_count, a_net->pub.name);
+            if ( dap_chain_net_srv_stake_get_total_keys(a_net->pub.id, NULL) == l_min_count ) {
+                log_it(L_WARNING, "Can't invalidate stake in net %s: results in minimum validators count %hu underflow",
+                                   a_net->pub.name, l_min_count);
                 return -116;
             }
             if (!a_apply)
diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h
index efb10ae09034e3c88c516ac61f973900b9e1760b..304a9037505539a26d3b511d569940396d014976 100644
--- a/modules/net/include/dap_chain_net.h
+++ b/modules/net/include/dap_chain_net.h
@@ -38,7 +38,9 @@ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/lic
 #include "dap_json_rpc_errors.h"
 
 #define DAP_CHAIN_NET_NAME_MAX 32
-#define DAP_CHAIN_NET_MEMPOOL_TTL 48 // Hours
+#define DAP_CHAIN_NET_MEMPOOL_TTL 4 * 3600  // 4 hours
+#define DAP_CHAIN_NET_NODES_TTL 14 * 24 * 3600   // 2 weeks
+
 
 typedef struct dap_chain_node_client dap_chain_node_client_t;
 typedef struct dap_ledger dap_ledger_t;
diff --git a/modules/net/include/dap_chain_net_balancer.h b/modules/net/include/dap_chain_net_balancer.h
index ccada8e10d97086f34654e607c3113a8a5bde7c2..4d314dbc7ed2e92c8a0cf656ba4177bbcb73cea6 100644
--- a/modules/net/include/dap_chain_net_balancer.h
+++ b/modules/net/include/dap_chain_net_balancer.h
@@ -55,10 +55,11 @@ typedef struct dap_balancer_link_request {
 DAP_STATIC_INLINE const char *dap_chain_net_balancer_type_to_str(dap_balancer_type_t a_type)
 {
     switch (a_type) {
-        case DAP_CHAIN_NET_BALANCER_TYPE_HTTP: return "HTTP";
-        case DAP_CHAIN_NET_BALANCER_TYPE_DNS: return "DNS";
-        default: return "UNDEFINED";
+    case DAP_CHAIN_NET_BALANCER_TYPE_HTTP:  return "HTTP";
+    case DAP_CHAIN_NET_BALANCER_TYPE_DNS:   return "DNS";
+    default: break;
     }
+    return "UNDEFINED";
 }
 void dap_chain_net_balancer_deinit();
 void dap_chain_net_balancer_http_issue_link(dap_http_simple_t *a_http_simple, void *a_arg);