diff --git a/CMakeLists.txt b/CMakeLists.txt
index e10449de202f38e8817f8babd3fb4e18bc4c46e4..3289a8bf8bfa5337a7de40060c8b1b383be512c5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -10,16 +10,10 @@ set(DAPSDK_MODULES "")
 
 if(NOT DEFINED CELLFRAME_MODULES)
     include (cmake/OS_Detection.cmake)
-    #if(LINUX)
-    #    set(CELLFRAME_MODULES "core chains mining network srv cs-dag-poa cs-block-poa cs-dag-pos cs-block-pos cs-block-ton cs-none srv-app srv-app-db srv-datum srv-stake srv-xchange modules-dynamic srv-vpn")
-    #elseif(WIN32 OR BSD OR DARWIN OR ANDROID)
-    #    set(CELLFRAME_MODULES "core chains mining network srv cs-dag-poa cs-block-poa cs-dag-pos cs-block-pos cs-block-ton cs-none srv-app srv-app-db srv-datum srv-stake srv-xchange")
-    #else()
-    #    set(CELLFRAME_MODULES "core chains network srv cs-dag-poa cs-block-poa cs-dag-pos cs-block-pos cs-block-ton cs-none srv-app srv-app-db srv-datum srv-stake srv-xchange")
-    #endif()
+
     set(CELLFRAME_MODULES "core chains mining network srv cs-dag-poa cs-block-poa cs-dag-pos cs-block-pos cs-block-ton cs-none srv-app srv-app-db srv-datum srv-stake-pos-delegate srv-stake-lock srv-xchange")
 
-    if(LINUX)
+    if(LINUX OR DARWIN)
         set(CELLFRAME_MODULES "${CELLFRAME_MODULES} modules-dynamic srv-vpn")
     endif()
 
diff --git a/dap-sdk/core/include/dap_common.h b/dap-sdk/core/include/dap_common.h
index 215619fff43bba717d1a508b03cc200e8599fb61..972a8b9902a62554eb219d0960c8b9d0cc812a5b 100755
--- a/dap-sdk/core/include/dap_common.h
+++ b/dap-sdk/core/include/dap_common.h
@@ -188,25 +188,14 @@ DAP_STATIC_INLINE void _dap_aligned_free( void *ptr )
 
 #define DAP_CLIENT_PROTOCOL_VERSION   24
 
-#if __SIZEOF_LONG__==8
+#if (__SIZEOF_LONG__ == 4) || defined (DAP_OS_DARWIN)
 #define DAP_UINT64_FORMAT_X  "llX"
 #define DAP_UINT64_FORMAT_x  "llx"
 #define DAP_UINT64_FORMAT_U  "llu"
-#ifdef DAP_OS_DARWIN
-#else
-#undef DAP_UINT64_FORMAT_X
-#undef DAP_UINT64_FORMAT_x
-#undef DAP_UINT64_FORMAT_U
-
-
+#elif (__SIZEOF_LONG__ == 8)
 #define DAP_UINT64_FORMAT_X  "lX"
 #define DAP_UINT64_FORMAT_x  "lx"
 #define DAP_UINT64_FORMAT_U  "lu"
-#endif
-#elif __SIZEOF_LONG__==4
-#define DAP_UINT64_FORMAT_X  "llX"
-#define DAP_UINT64_FORMAT_x  "llx"
-#define DAP_UINT64_FORMAT_U  "llu"
 #else
 #error "DAP_UINT64_FORMAT_* are undefined for your platform"
 #endif
diff --git a/dap-sdk/core/include/dap_time.h b/dap-sdk/core/include/dap_time.h
index 0c9a2fdf6400e983531b41925d4ded4a08be557c..696faeecc161c5661c4cb30310b10f0c510dc0a7 100644
--- a/dap-sdk/core/include/dap_time.h
+++ b/dap-sdk/core/include/dap_time.h
@@ -8,7 +8,8 @@
 #define DAP_NSEC_PER_SEC 1000000000
 // Constant to convert seconds to microseconds
 #define DAP_USEC_PER_SEC 1000000
-
+// Seconds per day
+#define DAP_SEC_PER_DAY 86400
 
 // time in seconds
 typedef uint64_t dap_time_t;
diff --git a/dap-sdk/core/src/dap_common.c b/dap-sdk/core/src/dap_common.c
index 99bdf2d28a888fa1b4f6f9502f9432681557eb4f..66dc2b24bef6250517c26917240d86b6303808ac 100755
--- a/dap-sdk/core/src/dap_common.c
+++ b/dap-sdk/core/src/dap_common.c
@@ -87,7 +87,6 @@ const uint128_t uint128_1 = 1;
 const uint256_t uint256_0 = {};
 #ifndef DAP_GLOBAL_IS_INT128
 const uint256_t uint256_1 = {.hi = {}, .lo = {.hi = 0, .lo = 1}};
-
 #else // DAP_GLOBAL_IS_INT128
 const uint256_t uint256_1 = {.hi = 0, .lo = 1};
 #endif // DAP_GLOBAL_IS_INT128
@@ -850,6 +849,7 @@ char * exec_with_ret(const char * a_cmd)
 FIN:
     return strdup(buf);
 }
+#endif
 
 /**
  * @brief exec_with_ret_multistring performs a command with a result return in the form of a multistring
@@ -876,7 +876,6 @@ char * exec_with_ret_multistring(const char * a_cmd)
 FIN:
     return strdup(retbuf);
 }
-#endif
 
 static const char l_possible_chars[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
 
diff --git a/dap-sdk/io/dap_events.c b/dap-sdk/io/dap_events.c
index cfed0115db52a984009f53f785824a93cd3be885..686dc229c0c4fcd95d0e568234c5e0f39e224337 100644
--- a/dap-sdk/io/dap_events.c
+++ b/dap-sdk/io/dap_events.c
@@ -395,7 +395,7 @@ dap_worker_t *dap_events_worker_get_auto( )
     if ( !s_workers_init )
         log_it(L_CRITICAL, "Event socket reactor has not been fired, use dap_events_init() first");
 
-    return s_workers[dap_events_thread_get_index_min()];
+    return s_workers[dap_events_worker_get_index_min()];
 }
 
 /**
diff --git a/modules/chain/dap_chain.c b/modules/chain/dap_chain.c
index 0dda11d24f9be86989eadaa87088e41acc6bcf38..c910fdfa481c2851c3c05b14b30935ad0dd53517 100644
--- a/modules/chain/dap_chain.c
+++ b/modules/chain/dap_chain.c
@@ -27,7 +27,10 @@
 #include <stdc-predef.h>
 #endif
 #include <unistd.h>
-
+#include "dap_chain_net_srv.h"
+#include "dap_chain_common.h"
+#include "dap_chain_datum.h"
+#include "dap_chain_datum_decree.h"
 #include "dap_chain_pvt.h"
 #include "dap_common.h"
 #include "dap_strfuncs.h"
diff --git a/modules/chain/dap_chain_ledger.c b/modules/chain/dap_chain_ledger.c
index 180094562ccd8439108922acc410cd9664936193..96faba554041418cd00d969afb37a88160478639 100644
--- a/modules/chain/dap_chain_ledger.c
+++ b/modules/chain/dap_chain_ledger.c
@@ -23,9 +23,6 @@
  along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "dap_chain_common.h"
-#include "dap_events.h"
-#include "dap_math_ops.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
@@ -47,6 +44,9 @@
 #include "uthash.h"
 #include "utlist.h"
 
+#include "dap_chain_common.h"
+#include "dap_events.h"
+#include "dap_math_ops.h"
 #include "dap_list.h"
 #include "dap_hash.h"
 #include "dap_string.h"
@@ -2453,94 +2453,82 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
             l_emission_hash = &l_tx_token->header.token_emission_hash;
             dap_chain_ledger_token_emission_item_t *l_emission_item = s_emission_item_find(a_ledger, l_token, l_emission_hash);
             if (!l_emission_item) {//check emission for STAKE_LOCK
-                dap_chain_datum_token_t* l_datum_token = dap_chain_ledger_token_ticker_check(a_ledger, l_token);
-                if (!l_datum_token ||
-                    l_datum_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_NATIVE_DECL) {
-                    debug_if(s_debug_more, L_WARNING, "tx_token [%s] not declareted or no type DAP_CHAIN_DATUM_TOKEN_TYPE_NATIVE_DECL", l_tx_token->header.ticker);
-                    l_err_num = -28;
-                    break;
-                }
-                if (!l_datum_token->header_native_decl.tsd_total_size) {
-                    debug_if(s_debug_more, L_WARNING, "No TSD section for tx_token [%s]", l_tx_token->header.ticker);
-                    l_err_num = -27;
-                    break;
-                }
-                dap_tsd_t* l_tsd;
-                if (NULL == (l_tsd = dap_tsd_find(l_datum_token->data_n_tsd, l_datum_token->header_native_decl.tsd_total_size, DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DELEGATE_EMISSION_FROM_STAKE_LOCK))) {
-                    debug_if(s_debug_more, L_WARNING, "No TSD section tyoe DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DELEGATE_EMISSION_FROM_STAKE_LOCK for tx_token [%s]", l_tx_token->header.ticker);
-                    l_err_num = -26;
-                    break;
-                }
-                dap_chain_datum_token_tsd_delegate_from_stake_lock_t l_tsd_section = dap_tsd_get_scalar(l_tsd, dap_chain_datum_token_tsd_delegate_from_stake_lock_t);
-                if (!dap_chain_ledger_token_ticker_check(a_ledger, l_tsd_section.ticker_token_from)) {
-                    debug_if(s_debug_more, L_WARNING, "tx_token [%s] no found", l_tsd_section.ticker_token_from);
-                    l_err_num = -23;
-                    break;
-                }
-                //				int item_count = 0;
-                dap_chain_tx_out_t* l_tx_out = (dap_chain_tx_out_t*)dap_chain_datum_tx_item_get(a_tx, 0, TX_ITEM_TYPE_OUT, 0);//TODO: ADD CHECK COUNT TX
-                if (!l_tx_out) {
-                    debug_if(s_debug_more, L_WARNING, "Can't find OUT item for base TX with tx_token [%s]", l_tx_token->header.ticker);
-                    l_err_num = -24;
-                    break;
-                }
-                dap_chain_datum_tx_t* l_tx_stake_lock = dap_chain_ledger_tx_find_by_hash(a_ledger, l_emission_hash);
-                dap_chain_tx_out_cond_t* l_tx_stake_lock_out_cond = (dap_chain_tx_out_cond_t*)dap_chain_datum_tx_item_get(l_tx_stake_lock, 0, TX_ITEM_TYPE_OUT_COND, 0);//TODO: ADD CHECK COUNT TX
-                if (!l_tx_stake_lock_out_cond) {
-                    debug_if(s_debug_more, L_WARNING, "No OUT_COND to for tx_token [%s]", l_tx_token->header.ticker);
-                    l_err_num = -30;
-                    break;
-                }
-                if (l_tx_stake_lock_out_cond->header.subtype != DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK) {
-                    debug_if(s_debug_more, L_WARNING, "OUT_COND is not stake_lock subtype to for tx_token [%s]", l_tx_token->header.ticker);
-                    l_err_num = -25;
-                    break;
-                }
-                uint256_t l_value_expected = {};
-                if (MULT_256_COIN(l_tx_stake_lock_out_cond->header.value, l_tsd_section.emission_rate, &l_value_expected) != 0) {
-                    if (s_debug_more) {
-                        char* l_emission_rate_str = dap_chain_balance_print(l_tsd_section.emission_rate);
-                        char* l_locked_value_str = dap_chain_balance_print(l_tx_stake_lock_out_cond->header.value);
-                        log_it(L_WARNING, "Multiplication overflow for %s emission: locked value %s emission rate %s"
+                dap_tsd_t *l_tsd;
+                dap_chain_datum_token_t *l_datum_token = dap_chain_ledger_token_ticker_check(a_ledger, l_token);
+                if (l_datum_token
+                &&	l_datum_token->type == DAP_CHAIN_DATUM_TOKEN_TYPE_NATIVE_DECL
+                &&	l_datum_token->header_native_decl.tsd_total_size
+                &&	NULL != (l_tsd = dap_tsd_find(l_datum_token->data_n_tsd, l_datum_token->header_native_decl.tsd_total_size, DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DELEGATE_EMISSION_FROM_STAKE_LOCK))) {
+                    dap_chain_datum_token_tsd_delegate_from_stake_lock_t l_tsd_section = dap_tsd_get_scalar(l_tsd, dap_chain_datum_token_tsd_delegate_from_stake_lock_t);
+                    if (!dap_chain_ledger_token_ticker_check(a_ledger, l_tsd_section.ticker_token_from)) {
+                        debug_if(s_debug_more, L_WARNING, "tx_token [%s] no found", l_tsd_section.ticker_token_from);
+                        l_err_num = -23;
+                        break;
+                    }
+//				int item_count = 0;
+                    dap_chain_tx_out_t *l_tx_out = (dap_chain_tx_out_t*)dap_chain_datum_tx_item_get(a_tx, 0, TX_ITEM_TYPE_OUT, 0);//TODO: ADD CHECK COUNT TX
+                    if (!l_tx_out) {
+                        debug_if(s_debug_more, L_WARNING, "Can't find OUT item for base TX with tx_token [%s]", l_tx_token->header.ticker);
+                        l_err_num = -24;
+                        break;
+                    }
+                    dap_chain_datum_tx_t *l_tx_stake_lock = dap_chain_ledger_tx_find_by_hash(a_ledger, l_emission_hash);
+                    dap_chain_tx_out_cond_t *l_tx_stake_lock_out_cond = (dap_chain_tx_out_cond_t*)dap_chain_datum_tx_item_get(l_tx_stake_lock, 0, TX_ITEM_TYPE_OUT_COND, 0);//TODO: ADD CHECK COUNT TX
+                    if (!l_tx_stake_lock_out_cond) {
+                        debug_if(s_debug_more, L_WARNING, "No OUT_COND to for tx_token [%s]", l_tx_token->header.ticker);
+                        l_err_num = -30;
+                        break;
+                    }
+                    if (l_tx_stake_lock_out_cond->header.subtype != DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK) {
+                        debug_if(s_debug_more, L_WARNING, "OUT_COND is not stake_lock subtype to for tx_token [%s]", l_tx_token->header.ticker);
+                        l_err_num = -25;
+                        break;
+                    }
+                    uint256_t l_value_expected ={};
+                    if (MULT_256_COIN(l_tx_stake_lock_out_cond->header.value, l_tsd_section.emission_rate, &l_value_expected)!=0){
+                        if(s_debug_more){
+                            char * l_emission_rate_str = dap_chain_balance_print(l_tsd_section.emission_rate);
+                            char * l_locked_value_str = dap_chain_balance_print(l_tx_stake_lock_out_cond->header.value);
+                            log_it( L_WARNING, "Multiplication overflow for %s emission: locked value %s emission rate %s"
                             , l_tx_token->header.ticker, l_locked_value_str, l_emission_rate_str);
-                        DAP_DELETE(l_emission_rate_str);
-                        DAP_DELETE(l_locked_value_str);
+                            DAP_DELETE(l_emission_rate_str);
+                            DAP_DELETE(l_locked_value_str);
+                        }
+                        l_err_num = -25;
+                        break;
                     }
-                    l_err_num = -25;
-                    break;
-                }
 
-                if (!EQUAL_256(l_value_expected, l_tx_out->header.value)) {
-                    char* l_value_expected_str = dap_chain_balance_print(l_value_expected);
-                    char* l_locked_value_str = dap_chain_balance_print(l_tx_out->header.value);
+                    if (!EQUAL_256(l_value_expected, l_tx_out->header.value)) {
+                        char * l_value_expected_str = dap_chain_balance_print(l_value_expected);
+                        char * l_locked_value_str = dap_chain_balance_print(l_tx_out->header.value);
 
-                    debug_if(s_debug_more, L_WARNING, "Value %s not thats expected %s for [%s]", l_locked_value_str, l_value_expected_str,
-                        l_tx_token->header.ticker);
+                        debug_if(s_debug_more, L_WARNING, "Value %s not thats expected %s for [%s]",l_locked_value_str, l_value_expected_str,
+                                 l_tx_token->header.ticker);
 
-                    DAP_DELETE(l_value_expected_str);
-                    DAP_DELETE(l_locked_value_str);
-                    l_err_num = -34;
-                    break;
-                }
-                // check tiker
-                const char* tx_tiker = dap_chain_ledger_tx_get_token_ticker_by_hash(a_ledger, l_emission_hash);
-                if (!tx_tiker) {
-                    debug_if(s_debug_more, L_WARNING, "No tiker stake_lock to for tx_token [%s]", l_tx_token->header.ticker);
-                    l_err_num = -33;
+                        DAP_DELETE(l_value_expected_str);
+                        DAP_DELETE(l_locked_value_str);
+                        l_err_num = -34;
+                        break;
+                    }
+                    // check tiker
+                    const char *tx_tiker = dap_chain_ledger_tx_get_token_ticker_by_hash(a_ledger, l_emission_hash);
+                    if (!tx_tiker) {
+                        debug_if(s_debug_more, L_WARNING, "No tiker stake_lock to for tx_token [%s]", l_tx_token->header.ticker);
+                        l_err_num = -33;
+                        break;
+                    }
+                    if (strcmp(tx_tiker, l_tsd_section.ticker_token_from)) {
+                        debug_if(s_debug_more, L_WARNING, "Tikers not equal for [%s]", l_tx_token->header.ticker);
+                        l_err_num = -34;
+                        break;
+                    }
+                    debug_if(s_debug_more, L_NOTICE, "Check emission passed for tx_token [%s]", l_tx_token->header.ticker);
                     break;
-                }
-                if (strcmp(tx_tiker, l_tsd_section.ticker_token_from)) {
-                    debug_if(s_debug_more, L_WARNING, "Tikers not equal for [%s]", l_tx_token->header.ticker);
-                    l_err_num = -34;
+                } else {
+                    debug_if(s_debug_more, L_WARNING, "Emission for tx_token [%s] wasn't found", l_tx_token->header.ticker);
+                    l_err_num = DAP_CHAIN_CS_VERIFY_CODE_TX_NO_EMISSION;
                     break;
                 }
-                debug_if(s_debug_more, L_NOTICE, "Check emission passed for tx_token [%s]", l_tx_token->header.ticker);
-                break;
-            }
-            if (!l_emission_item) {
-                debug_if(s_debug_more, L_WARNING, "Emission for tx_token [%s] wasn't found", l_tx_token->header.ticker);
-                l_err_num = DAP_CHAIN_CS_VERIFY_CODE_TX_NO_EMISSION;
-                break;
             }
             if (!dap_hash_fast_is_blank(&l_emission_item->tx_used_out)) {
                 debug_if(s_debug_more, L_WARNING, "Emission for tx_token [%s] is already used", l_tx_token->header.ticker);
diff --git a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c
index 412d2c6c9d5fe95b44b21776a2dc4a92a3ed3cb8..c106e86c13b2f4be4dff6ddb331beba83a25ecb8 100644
--- a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c
+++ b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c
@@ -365,7 +365,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg)
                 dap_stream_ch_chain_net_srv_pkt_test_t *l_request = (dap_stream_ch_chain_net_srv_pkt_test_t*) l_ch_pkt->data;
                 size_t l_request_size = l_request->data_size + sizeof(dap_stream_ch_chain_net_srv_pkt_test_t);
                 if (l_ch_pkt->hdr.size != l_request_size) {
-                    log_it(L_WARNING, "Wrong response size %u, required %zu", l_ch_pkt->hdr.size, l_request_size);
+                    log_it(L_WARNING, "Wrong request size %u, must be %zu [pkt seq %"DAP_UINT64_FORMAT_U"]", l_ch_pkt->hdr.size, l_request_size, l_ch_pkt->hdr.seq_id);
                     l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_WRONG_SIZE;
                     dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof(l_err));
                     break;
@@ -377,13 +377,14 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg)
                 dap_chain_hash_fast_t l_data_hash;
                 dap_hash_fast(l_request->data, l_request->data_size, &l_data_hash);
                 if (l_request->data_size > 0 && !dap_hash_fast_compare(&l_data_hash, &l_request->data_hash)) {
+                    log_it(L_WARNING, "Wrong hash [pkt seq %"DAP_UINT64_FORMAT_U"]", l_ch_pkt->hdr.seq_id);
                     l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_WRONG_HASH;
                     dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof(l_err));
                     break;
                 }
                 // The size of the received data is too large (> 4.294.967.295 bytes)
                 if(l_request->data_size_recv > UINT_MAX) {
-                    log_it(L_WARNING, "Too large size of data_size_recv=%zu", l_request->data_size_recv);
+                    log_it(L_WARNING, "Too large payload %zu [pkt seq %"DAP_UINT64_FORMAT_U"]", l_request->data_size_recv, l_ch_pkt->hdr.seq_id);
                     l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_BIG_SIZE;
                     dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err,
                             sizeof(l_err));
diff --git a/modules/channel/chain/dap_stream_ch_chain.c b/modules/channel/chain/dap_stream_ch_chain.c
index a1ee53ce3eae928d7417755b7abb158c7a3aa183..03e2325aff9b83640bdc1399260b905999fdd501 100644
--- a/modules/channel/chain/dap_stream_ch_chain.c
+++ b/modules/channel/chain/dap_stream_ch_chain.c
@@ -533,6 +533,7 @@ static bool s_sync_in_chains_callback(dap_proc_thread_t *a_thread, void *a_arg)
         if (s_debug_more) {
             log_it(L_INFO, "Thresholded atom with hash %s for %s:%s", l_atom_hash_str, l_chain->net_name, l_chain->name);
         }
+        dap_db_set_last_hash_remote(l_sync_request->request.node_addr.uint64, l_chain, &l_atom_hash);
         break;
     case ATOM_ACCEPT:
         if (s_debug_more) {
diff --git a/modules/consensus/block-poa/CMakeLists.txt b/modules/consensus/block-poa/CMakeLists.txt
index 76095fb37dd1d811d5d14f6a6e9e78ba30aeea8d..65426cad101cc232df6a4a3ccde628af513f3517 100644
--- a/modules/consensus/block-poa/CMakeLists.txt
+++ b/modules/consensus/block-poa/CMakeLists.txt
@@ -6,6 +6,6 @@ file(GLOB DAP_CHAIN_BLOCK_CS_POA_HEADERS include/*.h)
 
 add_library(${PROJECT_NAME} STATIC ${DAP_CHAIN_BLOCK_CS_POA_SRCS} ${DAP_CHAIN_BLOCK_CS_POA_HEADERS})
 
-target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_chain dap_chain_cs_blocks dap_chain_net_srv_stake)
+target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_chain dap_chain_cs_blocks dap_chain_net_srv_stake_pos_delegate)
 target_include_directories(${PROJECT_NAME} INTERFACE .)
 target_include_directories(${PROJECT_NAME} PUBLIC include)
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 b7a37f1f92639c851e07b3e66aa21cd9243cf874..5986f4d9a30a3de867c24cf5add76c465417826b 100644
--- a/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c
+++ b/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c
@@ -59,8 +59,15 @@ typedef struct dap_chain_cs_dag_poa_presign_callback{
     void *arg;
 } dap_chain_cs_dag_poa_presign_callback_t;
 
+struct round_timer_arg {
+    dap_chain_cs_dag_t *dag;
+    uint64_t round_id;
+    UT_hash_handle hh;
+};
+
 typedef struct dap_chain_cs_dag_poa_pvt {
     pthread_rwlock_t rounds_rwlock;
+    struct round_timer_arg *active_rounds;
     dap_cert_t * events_sign_cert;
     dap_cert_t ** auth_certs;
     char * auth_certs_prefix;
@@ -75,24 +82,19 @@ typedef struct dap_chain_cs_dag_poa_pvt {
 
 #define PVT(a) ((dap_chain_cs_dag_poa_pvt_t *) a->_pvt )
 
-typedef struct dap_chain_cs_dag_poa_callback_timer_arg {
-    dap_chain_cs_dag_t *dag;
-    uint64_t round_id;
-} dap_chain_cs_dag_poa_callback_timer_arg_t;
-
 static void s_callback_delete(dap_chain_cs_dag_t * a_dag);
 static int s_callback_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg);
-static bool s_poa_round_check(dap_chain_t *a_chain);
+static void s_poa_round_clean(void *a_arg);
 static int s_callback_created(dap_chain_t * a_chain, dap_config_t *a_chain_cfg);
 static int s_callback_event_verify(dap_chain_cs_dag_t * a_dag, dap_chain_cs_dag_event_t * a_dag_event, size_t a_dag_event_size);
 static dap_chain_cs_dag_event_t * s_callback_event_create(dap_chain_cs_dag_t * a_dag, dap_chain_datum_t * a_datum,
                                                           dap_chain_hash_fast_t * a_hashes, size_t a_hashes_count, size_t* a_event_size);
-static bool s_callback_round_event_to_chain(dap_chain_cs_dag_poa_callback_timer_arg_t * a_callback_arg);
+static bool s_callback_round_event_to_chain(struct round_timer_arg *a_arg);
 static int s_callback_event_round_sync(dap_chain_cs_dag_t * a_dag, const char a_op_code, const char *a_group,
                                         const char *a_key, const void *a_value, const size_t a_value_size);
 static bool s_round_event_ready_minimum_check(dap_chain_cs_dag_t *a_dag, dap_chain_cs_dag_event_t *a_event,
                                               size_t a_event_size, char *a_event_hash_hex_str);
-static void s_round_event_cs_done(dap_chain_cs_dag_t * a_dag, uint64_t a_round_id, dap_chain_cs_dag_event_round_info_t *a_event_round_info);
+static void s_round_event_cs_done(dap_chain_cs_dag_t * a_dag, uint64_t a_round_id);
 
 // CLI commands
 static int s_cli_dag_poa(int argc, char ** argv, char **str_reply);
@@ -257,9 +259,7 @@ static int s_cli_dag_poa(int argc, char ** argv, char **a_str_reply)
 
                 if ( l_event_size_new ) {
                     dap_chain_hash_fast_t l_event_new_hash;
-                    // dap_chain_cs_dag_event_calc_hash(l_event_new, l_event_size_new, &l_event_new_hash);
                     dap_chain_cs_dag_event_calc_hash(l_event, l_event_size_new, &l_event_new_hash);
-                    //size_t l_event_new_size = dap_chain_cs_dag_event_calc_size(l_event_new);
                     char * l_event_new_hash_hex_str = dap_chain_hash_fast_to_str_new(&l_event_new_hash);
                     char * l_event_new_hash_base58_str = dap_enc_base58_encode_hash_to_str(&l_event_new_hash);
 
@@ -279,11 +279,9 @@ static int s_cli_dag_poa(int argc, char ** argv, char **a_str_reply)
                                     l_poa_pvt->events_sign_cert->name, l_event_new_hash_base58_str);
                         }
                         ret = 0;
-                        // dap_chain_net_sync_gdb(l_chain_net); // Propagate changes in pool
                         if (l_event_is_ready && l_poa_pvt->auto_round_complete) // cs done (minimum signs & verify passed)
-                            s_round_event_cs_done(l_dag, l_event->header.round_id, &l_round_item->round_info);
-
-                    }else {
+                            s_round_event_cs_done(l_dag, l_event->header.round_id);
+                    } else {
                         if(!dap_strcmp(l_hash_out_type, "hex")) {
                             dap_chain_node_cli_set_reply_text(a_str_reply,
                                     "GDB Error: Can't place event %s with new sign back in round.new\n",
@@ -306,9 +304,8 @@ static int s_cli_dag_poa(int argc, char ** argv, char **a_str_reply)
                                                   l_event_hash_str);
                     ret=-1;
                 }
+                DAP_DELETE(l_round_item);
             }
-            // DAP_DELETE(l_event);
-            DAP_DELETE(l_round_item);
         } else {
             dap_chain_node_cli_set_reply_text(a_str_reply, "Command dag_poa requires subcommand 'sign'");
         }
@@ -377,9 +374,9 @@ static int s_callback_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg)
         dap_chain_node_role_t l_role = dap_chain_net_get_role(l_net);
         if (l_role.enums == NODE_ROLE_ROOT_MASTER || l_role.enums == NODE_ROLE_ROOT) {
             if (!s_poa_round_timer) {
-                s_poa_round_timer = dap_timerfd_start(10*1000, 
-                                (dap_timerfd_callback_t)s_poa_round_check, 
-                                a_chain);
+                s_poa_round_timer = dap_interval_timer_create(10 * 1000,
+                                                              s_poa_round_clean,
+                                                              a_chain);
                 log_it(L_MSG, "DAG-PoA: Round timer is started");
             }
         }
@@ -403,18 +400,19 @@ static int s_callback_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg)
 static bool s_poa_round_check_callback_round_clean(dap_global_db_context_t * a_global_db_context,int a_rc, const char * a_group, const char * a_key, const size_t a_values_total,  const size_t a_values_shift,
                                                   const size_t a_values_count, dap_global_db_obj_t * a_values, void * a_arg)
 {
-    dap_chain_t * l_chain = (dap_chain_t *) a_arg;
-    dap_chain_cs_dag_t *l_dag = DAP_CHAIN_CS_DAG(l_chain);
+    dap_chain_cs_dag_t *l_dag = (dap_chain_cs_dag_t *)a_arg;
     dap_chain_cs_dag_poa_t *l_poa = DAP_CHAIN_CS_DAG_POA(l_dag);
     dap_chain_cs_dag_poa_pvt_t *l_poa_pvt = PVT(l_poa);
 
     if (a_values_count) {
-        for (size_t i = 0; i<a_values_count; i++) {
+        for (size_t i = 0; i < a_values_count; i++) {
+            if (!strcmp(DAG_ROUND_CURRENT_KEY, a_values[i].key))
+                continue;
             dap_chain_cs_dag_event_round_item_t *l_event_round_item = (dap_chain_cs_dag_event_round_item_t *)a_values[i].value;
             uint64_t l_time_diff = dap_nanotime_now() - l_event_round_item->round_info.ts_update;
             uint64_t l_timeuot = dap_nanotime_from_sec(l_poa_pvt->confirmations_timeout + l_poa_pvt->wait_sync_before_complete + 10);
             uint64_t l_round_id = ((dap_chain_cs_dag_event_t *)l_event_round_item->event_n_signs)->header.round_id;
-            if (l_time_diff > l_timeuot && l_round_id < l_dag->round_completed) {
+            if (l_time_diff > l_timeuot && l_round_id <= l_dag->round_completed) {
                 dap_global_db_del_unsafe(a_global_db_context, a_group,  a_values[i].key);
                 log_it(L_DEBUG, "DAG-PoA: Remove event %s from round %"DAP_UINT64_FORMAT_U" by timer.",
                                 a_values[i].key, l_round_id);
@@ -429,12 +427,10 @@ static bool s_poa_round_check_callback_round_clean(dap_global_db_context_t * a_g
  * @param a_chain Chain object
  * @return Always true
  */
-static bool s_poa_round_check(dap_chain_t *a_chain) {
-    dap_chain_cs_dag_t *l_dag = DAP_CHAIN_CS_DAG(a_chain);
-
-    dap_global_db_get_all(l_dag->gdb_group_events_round_new,0,s_poa_round_check_callback_round_clean, a_chain );
-
-    return true;
+static void s_poa_round_clean(void *a_arg)
+{
+    dap_chain_cs_dag_t *l_dag = DAP_CHAIN_CS_DAG((dap_chain_t *)a_arg);
+    dap_global_db_get_all(l_dag->gdb_group_events_round_new,0,s_poa_round_check_callback_round_clean, l_dag);
 }
 
 static bool s_round_event_ready_minimum_check(dap_chain_cs_dag_t *a_dag, dap_chain_cs_dag_event_t *a_event,
@@ -444,7 +440,7 @@ static bool s_round_event_ready_minimum_check(dap_chain_cs_dag_t *a_dag, dap_cha
     dap_chain_cs_dag_poa_pvt_t *l_poa_pvt = PVT(l_poa);
     if ( a_event->header.signs_count < l_poa_pvt->auth_certs_count_verify)
         return false;
-    int l_ret_event_verify = a_dag->callback_cs_verify(a_dag, a_event, a_event_size);
+    int l_ret_event_verify = s_callback_event_verify(a_dag, a_event, a_event_size);
     if (l_ret_event_verify == 0)
         return true;
     log_it(L_ERROR,"Round auto-complete error! Event %s is not passing consensus verification, ret code %d\n",
@@ -452,28 +448,11 @@ static bool s_round_event_ready_minimum_check(dap_chain_cs_dag_t *a_dag, dap_cha
     return false;
 }
 
-static void s_round_event_cs_done(dap_chain_cs_dag_t * a_dag, uint64_t a_round_id, dap_chain_cs_dag_event_round_info_t *a_event_round_info)
-{
-    dap_chain_cs_dag_poa_t * l_poa = DAP_CHAIN_CS_DAG_POA( a_dag );
-    dap_chain_cs_dag_poa_callback_timer_arg_t * l_callback_arg = DAP_NEW_Z(dap_chain_cs_dag_poa_callback_timer_arg_t);
-    l_callback_arg->dag = a_dag;
-    l_callback_arg->round_id = a_round_id;
-    l_callback_arg->round_id = a_round_id;
-    long l_timediff = dap_gdb_time_to_sec(a_event_round_info->ts_update - dap_nanotime_now());
-    int l_timeout = l_timediff + PVT(l_poa)->confirmations_timeout;
-    // placement in chain by timer
-    if (dap_timerfd_start(l_timeout * 1000,
-                        (dap_timerfd_callback_t)s_callback_round_event_to_chain,
-                        l_callback_arg) == NULL)
-        log_it(L_ERROR,"Can't run timer for round ID %"DAP_UINT64_FORMAT_U, a_round_id);
-    else
-        log_it(L_NOTICE,"Run timer for %d sec for round ID %"DAP_UINT64_FORMAT_U, l_timeout, a_round_id);
-}
-
 enum dap_chain_poa_round_filter_stage {
     DAP_CHAIN_POA_ROUND_FILTER_STAGE_START,
     DAP_CHAIN_POA_ROUND_FILTER_STAGE_SIGNS,
     DAP_CHAIN_POA_ROUND_FILTER_STAGE_TS,
+    DAP_CHAIN_POA_ROUND_FILTER_STAGE_HASH,
     DAP_CHAIN_POA_ROUND_FILTER_STAGE_MAX
 };
 
@@ -485,6 +464,7 @@ static dap_chain_cs_dag_event_round_item_t *s_round_event_choose_dup(dap_list_t
         return NULL;
     dap_list_t *l_dups = dap_list_copy(a_dups);
     uint64_t l_min_ts_update = (uint64_t)-1;
+    dap_hash_fast_t l_event_hash, l_winner_hash = {};
     enum dap_chain_poa_round_filter_stage l_stage = DAP_CHAIN_POA_ROUND_FILTER_STAGE_START;
     while (l_stage++ < DAP_CHAIN_POA_ROUND_FILTER_STAGE_MAX) {
         for (dap_list_t *it = l_dups; it; it = it->next) {
@@ -492,14 +472,26 @@ static dap_chain_cs_dag_event_round_item_t *s_round_event_choose_dup(dap_list_t
             l_event = (dap_chain_cs_dag_event_t *)l_round_item->event_n_signs;
             switch (l_stage) {
             case DAP_CHAIN_POA_ROUND_FILTER_STAGE_SIGNS:
-                if (l_event->header.signs_count < a_max_signs_counts)
-                    dap_list_remove_link(l_dups, it);
+                if (l_event->header.signs_count != a_max_signs_counts)
+                    l_dups = dap_list_remove_link(l_dups, it);
                 else if (l_round_item->round_info.ts_update < l_min_ts_update)
                     l_min_ts_update = l_round_item->round_info.ts_update;
                 break;
             case DAP_CHAIN_POA_ROUND_FILTER_STAGE_TS:
-                if (l_round_item->round_info.ts_update > l_min_ts_update)
-                    dap_list_remove_link(l_dups, it);
+                if (l_round_item->round_info.ts_update != l_min_ts_update)
+                    l_dups = dap_list_remove_link(l_dups, it);
+                else {
+                    dap_chain_cs_dag_event_calc_hash((dap_chain_cs_dag_event_t *)l_round_item->event_n_signs,
+                                                     l_round_item->event_size, &l_event_hash);
+                    if (memcmp(&l_winner_hash, &l_event_hash, sizeof(dap_hash_fast_t)) < 0)
+                        memcpy(&l_winner_hash, &l_event_hash, sizeof(dap_hash_fast_t));
+                }
+                break;
+            case DAP_CHAIN_POA_ROUND_FILTER_STAGE_HASH:
+                dap_chain_cs_dag_event_calc_hash((dap_chain_cs_dag_event_t *)l_round_item->event_n_signs,
+                                                 l_round_item->event_size, &l_event_hash);
+                if (memcmp(&l_winner_hash, &l_event_hash, sizeof(dap_hash_fast_t)))
+                    l_dups = dap_list_remove_link(l_dups, it);
             default: break;
             }
         }
@@ -514,7 +506,7 @@ static dap_chain_cs_dag_event_round_item_t *s_round_event_choose_dup(dap_list_t
     }
     log_it(L_ERROR, "POA rounds filtering: Can't choose only one item with current filters, need to increase it's number");
     l_round_item = (dap_chain_cs_dag_event_round_item_t *)l_dups->data;
-    dap_list_free_full(l_dups, NULL);
+    dap_list_free(l_dups);
     return l_round_item;
 }
 
@@ -538,8 +530,9 @@ static bool s_callback_round_event_to_chain_callback_get_round_item(dap_global_d
 {
     if (a_rc != DAP_GLOBAL_DB_RC_SUCCESS)
         return true;
-    dap_chain_cs_dag_poa_callback_timer_arg_t *l_arg = (dap_chain_cs_dag_poa_callback_timer_arg_t *)a_arg;
+    struct round_timer_arg *l_arg = (struct round_timer_arg *)a_arg;
     dap_chain_cs_dag_t *l_dag = l_arg->dag;
+    dap_chain_cs_dag_poa_pvt_t *l_poa_pvt = PVT(DAP_CHAIN_CS_DAG_POA(l_dag));
     size_t l_events_round_size = a_values_count;
     dap_store_obj_t *l_events_round = a_values;
     uint16_t l_max_signs_count = 0;
@@ -548,36 +541,40 @@ static bool s_callback_round_event_to_chain_callback_get_round_item(dap_global_d
         dap_chain_cs_dag_event_round_item_t *l_round_item = (dap_chain_cs_dag_event_round_item_t *)l_events_round[l_index].value;
         dap_chain_cs_dag_event_t *l_event = (dap_chain_cs_dag_event_t *)l_round_item->event_n_signs;
         if (l_event->header.round_id == l_arg->round_id &&
-                l_round_item->round_info.reject_count < PVT(DAP_CHAIN_CS_DAG_POA(l_dag))->auth_certs_count_verify) {
+                l_round_item->round_info.reject_count < l_poa_pvt->auth_certs_count_verify) {
             l_dups_list = dap_list_append(l_dups_list, l_round_item);
             if (l_event->header.signs_count > l_max_signs_count)
                 l_max_signs_count = l_event->header.signs_count;
         }
     }
     dap_chain_cs_dag_event_round_item_t *l_chosen_item = s_round_event_choose_dup(l_dups_list, l_max_signs_count);
-    dap_list_free_full(l_dups_list, NULL);
-    if (!l_chosen_item) {
+    dap_chain_cs_dag_event_t *l_new_atom = NULL;
+    if (l_chosen_item) {
+        size_t l_event_size = l_chosen_item->event_size;
+        l_new_atom = dap_chain_cs_dag_event_copy((dap_chain_cs_dag_event_t *)l_chosen_item->event_n_signs, l_event_size);
+        dap_hash_fast_t l_event_hash = {};
+        dap_hash_fast(l_new_atom, l_event_size, &l_event_hash);
+        char l_event_hash_hex_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
+        dap_hash_fast_to_str(&l_event_hash, l_event_hash_hex_str, DAP_CHAIN_HASH_FAST_STR_SIZE);
+        dap_chain_atom_verify_res_t l_res = l_dag->chain->callback_atom_add(l_dag->chain, l_new_atom, l_event_size);
+        if (l_res == ATOM_PASS || l_res == ATOM_REJECT) { // Add new atom in chain
+            DAP_DEL_Z(l_new_atom);
+            log_it(L_NOTICE, "Event %s from round %"DAP_UINT64_FORMAT_U" not added in chain", l_event_hash_hex_str, l_arg->round_id);
+        } else {
+            log_it(L_NOTICE, "Event %s from round %"DAP_UINT64_FORMAT_U" added in %s successfully", l_event_hash_hex_str, l_arg->round_id,
+                                                                  l_res == ATOM_ACCEPT ? "chain" : "threshold");
+            if (l_res == ATOM_ACCEPT)
+                dap_chain_atom_save(l_dag->chain, (dap_chain_atom_ptr_t)l_new_atom, l_event_size, l_dag->chain->cells->id);
+        }
+    } else
         log_it(L_WARNING, "No round candidates for round ID %"DAP_UINT64_FORMAT_U, l_arg->round_id);
-        return true;
-    }
-    size_t l_event_size = l_chosen_item->event_size;
-    dap_chain_atom_ptr_t l_new_atom = (dap_chain_atom_ptr_t)dap_chain_cs_dag_event_copy(
-                (dap_chain_cs_dag_event_t *)l_chosen_item->event_n_signs, l_event_size);
-    DAP_DELETE(l_chosen_item);
-    dap_hash_fast_t l_event_hash = {};
-    dap_hash_fast(l_new_atom, l_event_size, &l_event_hash);
-    char l_event_hash_hex_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
-    dap_hash_fast_to_str(&l_event_hash, l_new_atom, DAP_CHAIN_HASH_FAST_STR_SIZE);
-    dap_chain_atom_verify_res_t l_res = l_dag->chain->callback_atom_add(l_dag->chain, l_new_atom, l_event_size);
-    if (l_res == ATOM_PASS || l_res == ATOM_REJECT) { // Add new atom in chain
-        DAP_DELETE(l_new_atom);
-        log_it(L_NOTICE, "Event %s from round %"DAP_UINT64_FORMAT_U" not added in chain", l_event_hash_hex_str, l_arg->round_id);
-    } else {
-        log_it(L_NOTICE, "Event %s from round %"DAP_UINT64_FORMAT_U"added in %s successfully", l_event_hash_hex_str, l_arg->round_id,
-                                                              l_res == ATOM_ACCEPT ? "chain" : "threshold");
-        if (l_res == ATOM_ACCEPT)
-            dap_chain_atom_save(l_dag->chain, l_new_atom, l_event_size, l_dag->chain->cells->id);
-    }
+    pthread_rwlock_wrlock(&l_poa_pvt->rounds_rwlock);
+    HASH_DEL(l_poa_pvt->active_rounds, l_arg);
+    if (!l_new_atom || !l_new_atom->header.round_id)
+        l_dag->round_completed++;
+    pthread_rwlock_unlock(&l_poa_pvt->rounds_rwlock);
+    dap_list_free(l_dups_list);
+    dap_store_obj_free(l_events_round, l_events_round_size);
     DAP_DELETE(a_arg);
     return true;
 }
@@ -587,7 +584,7 @@ static bool s_callback_round_event_to_chain_callback_get_round_item(dap_global_d
  * @param a_callback_arg
  * @return
  */
-static bool s_callback_round_event_to_chain(dap_chain_cs_dag_poa_callback_timer_arg_t *a_callback_arg)
+static bool s_callback_round_event_to_chain(struct round_timer_arg *a_callback_arg)
 {
     dap_chain_cs_dag_t * l_dag = a_callback_arg->dag;
     char * l_gdb_group_events = l_dag->gdb_group_events_round_new;
@@ -595,6 +592,33 @@ static bool s_callback_round_event_to_chain(dap_chain_cs_dag_poa_callback_timer_
     return false;
 }
 
+static void s_round_event_cs_done(dap_chain_cs_dag_t * a_dag, uint64_t a_round_id)
+{
+    dap_chain_cs_dag_poa_t *l_poa = DAP_CHAIN_CS_DAG_POA(a_dag);
+    dap_chain_cs_dag_poa_pvt_t *l_poa_pvt = PVT(l_poa);
+    struct round_timer_arg *l_callback_arg;
+    pthread_rwlock_wrlock(&l_poa_pvt->rounds_rwlock);
+    HASH_FIND(hh, l_poa_pvt->active_rounds, &a_round_id, sizeof(uint64_t), l_callback_arg);
+    if (l_callback_arg) {
+        pthread_rwlock_unlock(&l_poa_pvt->rounds_rwlock);
+        return;
+    }
+    l_callback_arg = DAP_NEW_Z(struct round_timer_arg);
+    l_callback_arg->dag = a_dag;
+    l_callback_arg->round_id = a_round_id;
+    // placement in chain by timer
+    if (dap_timerfd_start(PVT(l_poa)->confirmations_timeout * 1000,
+                          (dap_timerfd_callback_t)s_callback_round_event_to_chain,
+                          l_callback_arg) == NULL) {
+        log_it(L_ERROR,"Can't run timer for round ID %"DAP_UINT64_FORMAT_U, a_round_id);
+        pthread_rwlock_unlock(&l_poa_pvt->rounds_rwlock);
+        return;
+    }
+    log_it(L_NOTICE,"Run timer for %d sec for round ID %"DAP_UINT64_FORMAT_U, PVT(l_poa)->confirmations_timeout, a_round_id);
+    HASH_ADD(hh, l_poa_pvt->active_rounds, round_id, sizeof(uint64_t), l_callback_arg);
+    pthread_rwlock_unlock(&l_poa_pvt->rounds_rwlock);
+}
+
 /**
  * @brief create callback load certificate for event signing for specific chain
  * path to certificate iw written to chain config file in dag_poa section
@@ -629,6 +653,7 @@ static int s_callback_created(dap_chain_t * a_chain, dap_config_t *a_chain_net_c
  */
 static void s_callback_delete(dap_chain_cs_dag_t * a_dag)
 {
+    dap_interval_timer_delete(s_poa_round_timer);
     dap_chain_cs_dag_poa_t * l_poa = DAP_CHAIN_CS_DAG_POA ( a_dag );
 
     if ( l_poa->_pvt ) {
@@ -672,12 +697,14 @@ static dap_chain_cs_dag_event_t * s_callback_event_create(dap_chain_cs_dag_t * a
     }
     if ( s_seed_mode || (a_hashes && a_hashes_count) ){
         if ( !PVT(l_poa)->callback_pre_sign || !PVT(l_poa)->callback_pre_sign->callback) {
-            dap_chain_cs_dag_event_t * l_event = dap_chain_cs_dag_event_new( a_dag->chain->id, a_dag->chain->cells->id, a_datum,
-                                                             PVT(l_poa)->events_sign_cert->enc_key, a_hashes, a_hashes_count, a_event_size);
+            dap_chain_cs_dag_event_t * l_event = dap_chain_cs_dag_event_new(a_dag->chain->id, a_dag->chain->cells->id, a_dag->round_current,
+                                                                            a_datum, PVT(l_poa)->events_sign_cert->enc_key,
+                                                                            a_hashes, a_hashes_count, a_event_size);
             return l_event;
         } else {
-            dap_chain_cs_dag_event_t *l_event = dap_chain_cs_dag_event_new(a_dag->chain->id, a_dag->chain->cells->id, a_datum,
-                                                                            NULL, a_hashes, a_hashes_count, a_event_size);
+            dap_chain_cs_dag_event_t *l_event = dap_chain_cs_dag_event_new(a_dag->chain->id, a_dag->chain->cells->id, a_dag->round_current,
+                                                                           a_datum, NULL,
+                                                                           a_hashes, a_hashes_count, a_event_size);
             int ret = PVT(l_poa)->callback_pre_sign->callback(a_dag->chain, l_event, *a_event_size, PVT(l_poa)->callback_pre_sign->arg);
             if (ret) {
                 DAP_DELETE(l_event);
@@ -697,10 +724,12 @@ static int s_callback_event_round_sync(dap_chain_cs_dag_t * a_dag, const char a_
         return 0;
 
     dap_chain_cs_dag_poa_t * l_poa = DAP_CHAIN_CS_DAG_POA(a_dag);
-    if (!PVT(l_poa)->events_sign_cert)
+    dap_chain_cs_dag_poa_pvt_t *l_poa_pvt = PVT(l_poa);
+
+    if (!l_poa_pvt->events_sign_cert)
         return -1;
 
-    if (!PVT(l_poa)->auto_confirmation)
+    if (!l_poa_pvt->auto_confirmation)
         return 0;
 
     dap_chain_cs_dag_event_round_item_t *l_round_item = (dap_chain_cs_dag_event_round_item_t *)a_value;
@@ -708,44 +737,49 @@ static int s_callback_event_round_sync(dap_chain_cs_dag_t * a_dag, const char a_
     dap_chain_cs_dag_event_t *l_event = (dap_chain_cs_dag_event_t *)l_round_item->event_n_signs;
 
     if (l_event->header.round_id < a_dag->round_completed) {
-        log_it(L_DEBUG, "DAG event came from too old round so won't be processed");
-        return -2;
+        struct round_timer_arg *l_round_active;
+        uint64_t l_round_id = l_event->header.round_id;
+        pthread_rwlock_wrlock(&l_poa_pvt->rounds_rwlock);
+        HASH_FIND(hh, l_poa_pvt->active_rounds, &l_round_id, sizeof(uint64_t), l_round_active);
+        pthread_rwlock_unlock(&l_poa_pvt->rounds_rwlock);
+        if (!l_round_active) {
+            log_it(L_DEBUG, "DAG event came from too old round so won't be processed");
+            return -2;
+        }
     }
 
-    if (dap_chain_cs_dag_event_sign_exists(l_event, l_event_size, PVT(l_poa)->events_sign_cert->enc_key)
-            || dap_chain_cs_dag_event_round_sign_exists(l_round_item, PVT(l_poa)->events_sign_cert->enc_key)) {
+    if (dap_chain_cs_dag_event_sign_exists(l_event, l_event_size, l_poa_pvt->events_sign_cert->enc_key)
+            || dap_chain_cs_dag_event_round_sign_exists(l_round_item, l_poa_pvt->events_sign_cert->enc_key)) {
         // if my sign exists
-        if (PVT(l_poa)->auto_round_complete &&
+        if (l_poa_pvt->auto_round_complete &&
                 s_round_event_ready_minimum_check(a_dag, l_event, l_event_size, (char *)a_key))
             // cs done (minimum signs & verify passed)
-            s_round_event_cs_done(a_dag, l_event->header.round_id, &l_round_item->round_info);
+            s_round_event_cs_done(a_dag, l_event->header.round_id);
         return 0;
     }
 
     size_t l_event_size_new = 0;
     int ret = 0;
-    if (!PVT(l_poa)->callback_pre_sign || !PVT(l_poa)->callback_pre_sign->callback ||
-             !(ret = PVT(l_poa)->callback_pre_sign->callback(a_dag->chain, l_event, l_event_size,
-                                                      PVT(l_poa)->callback_pre_sign->arg))) {
+    if (!l_poa_pvt->callback_pre_sign || !l_poa_pvt->callback_pre_sign->callback ||
+             !(ret = l_poa_pvt->callback_pre_sign->callback(a_dag->chain, l_event, l_event_size,
+                                                      l_poa_pvt->callback_pre_sign->arg))) {
         l_event = DAP_DUP_SIZE(l_round_item->event_n_signs, l_event_size);
-        l_event_size_new = dap_chain_cs_dag_event_sign_add(&l_event, l_event_size, PVT(l_poa)->events_sign_cert->enc_key);
+        l_event_size_new = dap_chain_cs_dag_event_sign_add(&l_event, l_event_size, l_poa_pvt->events_sign_cert->enc_key);
         dap_chain_hash_fast_t l_event_new_hash;
         dap_chain_cs_dag_event_calc_hash(l_event, l_event_size_new, &l_event_new_hash);
         char *l_event_new_hash_hex_str = dap_chain_hash_fast_to_str_new(&l_event_new_hash);
-        dap_chain_cs_dag_event_gdb_set(a_dag, l_event_new_hash_hex_str, l_event,
-                                            l_event_size_new, l_round_item);
+        dap_chain_cs_dag_event_gdb_set(a_dag, l_event_new_hash_hex_str, l_event, l_event_size_new, l_round_item);
         DAP_DELETE(l_event_new_hash_hex_str);
         DAP_DELETE(l_event);
     } else { // set sign for reject
         l_round_item = DAP_DUP_SIZE(a_value, a_value_size);
-        if (dap_chain_cs_dag_event_round_sign_add(&l_round_item, a_value_size, PVT(l_poa)->events_sign_cert->enc_key)) {
+        if (dap_chain_cs_dag_event_round_sign_add(&l_round_item, a_value_size, l_poa_pvt->events_sign_cert->enc_key)) {
             log_it(L_NOTICE,"Can't sign event %s, because sign rejected by pre_sign callback, ret code=%d", a_key, ret);
             l_round_item->round_info.reject_count++;
             dap_chain_cs_dag_event_gdb_set(a_dag, (char *)a_key, l_event, l_event_size, l_round_item);
         }
         DAP_DELETE(l_round_item);
     }
-    DAP_DELETE(l_event);
     return 0;
 }
 
@@ -768,7 +802,7 @@ static int s_callback_event_verify(dap_chain_cs_dag_t * a_dag, dap_chain_cs_dag_
         return -7; // Incorrest size
     }
     uint16_t l_certs_count_verify = l_poa_pvt->auth_certs_count_verify;
-    if ( a_event->header.signs_count >= l_certs_count_verify ){
+    if (a_event->header.signs_count >= l_certs_count_verify) {
         size_t l_signs_count = 0;
         dap_sign_t **l_signs = dap_sign_get_unique_signs(((uint8_t*)a_event)+l_offset_from_beginning,
                                                 a_event_size-l_offset_from_beginning, &l_signs_count);
diff --git a/modules/consensus/dag-pos/dap_chain_cs_dag_pos.c b/modules/consensus/dag-pos/dap_chain_cs_dag_pos.c
index eeb7fa482263e22daae53b70223d93a35658af53..348c61c5d87f02a0a92b60fbe6e62be6370f0cee 100644
--- a/modules/consensus/dag-pos/dap_chain_cs_dag_pos.c
+++ b/modules/consensus/dag-pos/dap_chain_cs_dag_pos.c
@@ -206,7 +206,7 @@ static dap_chain_cs_dag_event_t * s_callback_event_create(dap_chain_cs_dag_t * a
         return NULL;
     }
     if(a_datum || (a_hashes && a_hashes_count)) {
-        dap_chain_cs_dag_event_t * l_event = dap_chain_cs_dag_event_new(a_dag->chain->id, a_dag->chain->cells->id, a_datum,
+        dap_chain_cs_dag_event_t * l_event = dap_chain_cs_dag_event_new(a_dag->chain->id, a_dag->chain->cells->id, a_dag->round_current, a_datum,
                                                                         PVT(l_pos)->events_sign_key, a_hashes, a_hashes_count, a_dag_event_size);
         return l_event;
     } else
diff --git a/modules/global-db/dap_global_db.c b/modules/global-db/dap_global_db.c
index 9b83a0959123bdbcbb76631a163efdd59532b36e..b41cec13fa896ba21f57e3c08e2bb240d7044597 100644
--- a/modules/global-db/dap_global_db.c
+++ b/modules/global-db/dap_global_db.c
@@ -1503,7 +1503,7 @@ int dap_global_db_del_unsafe(dap_global_db_context_t * a_global_db_context, cons
     if (a_key) {
         if (l_res >= 0) {
             // add to Del group
-            l_res = s_record_del_history_add(l_store_obj.group, l_store_obj.key, dap_nanotime_now() );
+            l_res = s_record_del_history_add(l_store_obj.group, (char *)l_store_obj.key, dap_nanotime_now() );
         }
         // do not add to history if l_res=1 (already deleted)
         if (!l_res) {
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index 6f5203e1e3392db2a4b7609c022b3e0e36af9a86..9efe26944d68b2b910f9694d23dff29dff51aad7 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -84,7 +84,9 @@
 
 #include "dap_enc_http.h"
 #include "dap_chain_common.h"
+#include "dap_chain_datum_decree.h"
 #include "dap_chain_net.h"
+#include "dap_chain_net_srv.h"
 #include "dap_chain_pvt.h"
 #include "dap_chain_node_client.h"
 #include "dap_chain_node_cli.h"
@@ -3280,6 +3282,163 @@ void dap_chain_net_proc_mempool (dap_chain_net_t * a_net)
     }
 }
 
+/**
+ * @brief For now it returns all COND_IN transactions
+ * @param a_net
+ * @param a_srv_uid
+ * @param a_search_type
+ * @return Hash lists of dap_chain_datum_tx_item_t with conditional transaction and it spending if present
+ */
+dap_chain_datum_tx_spends_items_t * dap_chain_net_get_tx_cond_all_with_spends_by_srv_uid(dap_chain_net_t * a_net, const dap_chain_net_srv_uid_t a_srv_uid,
+                                                      const dap_time_t a_time_from, const dap_time_t a_time_to,
+                                                     const dap_chain_net_tx_search_type_t a_search_type)
+{
+    dap_ledger_t * l_ledger = a_net->pub.ledger;
+    dap_chain_datum_tx_spends_items_t * l_ret = DAP_NEW_Z(dap_chain_datum_tx_spends_items_t);
+
+    switch (a_search_type) {
+        case TX_SEARCH_TYPE_NET:
+        case TX_SEARCH_TYPE_CELL:
+        case TX_SEARCH_TYPE_LOCAL:
+        case TX_SEARCH_TYPE_CELL_SPENT:
+        case TX_SEARCH_TYPE_NET_UNSPENT:
+        case TX_SEARCH_TYPE_CELL_UNSPENT:
+        case TX_SEARCH_TYPE_NET_SPENT: {
+            // pass all chains
+            for ( dap_chain_t * l_chain = a_net->pub.chains; l_chain; l_chain = l_chain->next){
+                dap_chain_cell_t * l_cell, *l_cell_tmp;
+                // Go through all cells
+                HASH_ITER(hh,l_chain->cells,l_cell, l_cell_tmp){
+                    dap_chain_atom_iter_t * l_atom_iter = l_chain->callback_atom_iter_create(l_chain,l_cell->id, false  );
+                    // try to find transaction in chain ( inside shard )
+                    size_t l_atom_size = 0;
+                    dap_chain_atom_ptr_t l_atom = l_chain->callback_atom_iter_get_first(l_atom_iter, &l_atom_size);
+
+                    // Check atoms in chain
+                    while(l_atom && l_atom_size) {
+                        size_t l_datums_count = 0;
+                        dap_chain_datum_t **l_datums = l_chain->callback_atom_get_datums(l_atom, l_atom_size, &l_datums_count);
+                        // transaction
+                        dap_chain_datum_tx_t *l_tx = NULL;
+
+                        for (size_t i = 0; i < l_datums_count; i++) {
+                            // Check if its transaction
+                            if (l_datums && (l_datums[i]->header.type_id == DAP_CHAIN_DATUM_TX)) {
+                                l_tx = (dap_chain_datum_tx_t *)l_datums[i]->data;
+                            }
+
+                            // If found TX
+                            if (l_tx){
+                                // Check for time from
+                                if(a_time_from && l_tx->header.ts_created < a_time_from)
+                                        continue;
+
+                                // Check for time to
+                                if(a_time_to && l_tx->header.ts_created > a_time_to)
+                                        continue;
+
+                                if(a_search_type == TX_SEARCH_TYPE_CELL_SPENT || a_search_type == TX_SEARCH_TYPE_NET_SPENT ){
+                                    dap_hash_fast_t * l_tx_hash = dap_chain_node_datum_tx_calc_hash(l_tx);
+                                    bool l_is_spent = dap_chain_ledger_tx_spent_find_by_hash(l_ledger,l_tx_hash);
+                                    DAP_DELETE(l_tx_hash);
+                                    if(!l_is_spent)
+                                        continue;
+                                }
+
+                                // Go through all items
+                                uint32_t l_tx_items_pos = 0, l_tx_items_size = l_tx->header.tx_items_size;
+                                int l_item_idx = 0;
+                                while (l_tx_items_pos < l_tx_items_size) {
+                                    uint8_t *l_item = l_tx->tx_items + l_tx_items_pos;
+                                    int l_item_size = dap_chain_datum_item_tx_get_size(l_item);
+                                    if(!l_item_size)
+                                        break;
+                                    // check type
+                                    dap_chain_tx_item_type_t l_item_type = dap_chain_datum_tx_item_get_type(l_item);
+                                    switch (l_item_type){
+                                        case TX_ITEM_TYPE_IN_COND:{
+                                            dap_chain_tx_in_cond_t * l_tx_in_cond = (dap_chain_tx_in_cond_t *) l_item;
+                                            dap_chain_datum_tx_spends_item_t  *l_tx_prev_out_item = NULL;
+                                            HASH_FIND(hh, l_ret->tx_outs, &l_tx_in_cond->header.tx_prev_hash,sizeof(l_tx_in_cond->header.tx_prev_hash), l_tx_prev_out_item);
+
+                                            if (l_tx_prev_out_item){ // we found previous out_cond with target srv_uid
+                                                dap_chain_datum_tx_spends_item_t *l_item_in = DAP_NEW_Z(dap_chain_datum_tx_spends_item_t);
+                                                size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx);
+                                                dap_chain_datum_tx_t * l_tx_dup = DAP_DUP_SIZE(l_tx,l_tx_size);
+                                                dap_hash_fast(l_tx_dup,l_tx_size, &l_item_in->tx_hash);
+
+                                                l_item_in->tx = l_tx_dup;
+                                                // Calc same offset from tx duplicate
+                                                l_item_in->in_cond = (dap_chain_tx_in_cond_t*) (l_tx_dup->tx_items + l_tx_items_pos);
+                                                HASH_ADD_KEYPTR(hh,l_ret->tx_ins, &l_item_in->tx_hash, sizeof(l_item_in->tx_hash), l_item_in);
+
+                                                // Link previous out with current in
+                                                l_tx_prev_out_item->tx_next = l_tx_dup;
+                                            }
+                                        }break;
+                                        case TX_ITEM_TYPE_OUT_COND:{
+                                            dap_chain_tx_out_cond_t * l_tx_out_cond = (dap_chain_tx_out_cond_t *)l_item;
+                                            if(l_tx_out_cond->header.srv_uid.uint64 == a_srv_uid.uint64){
+                                                dap_chain_datum_tx_spends_item_t * l_item = DAP_NEW_Z(dap_chain_datum_tx_spends_item_t);
+                                                size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx);
+                                                dap_chain_datum_tx_t * l_tx_dup = DAP_DUP_SIZE(l_tx,l_tx_size);
+                                                dap_hash_fast(l_tx,l_tx_size, &l_item->tx_hash);
+                                                l_item->tx = l_tx_dup;
+                                                // Calc same offset from tx duplicate
+                                                l_item->out_cond = (dap_chain_tx_out_cond_t*) (l_tx_dup->tx_items + l_tx_items_pos);
+
+                                                HASH_ADD_KEYPTR(hh,l_ret->tx_outs, &l_item->tx_hash, sizeof(l_item->tx_hash), l_item);
+                                                break; // We're seaching only for one specified OUT_COND output per transaction
+                                            }
+                                        } break;
+                                        default:;
+                                    }
+
+                                    l_tx_items_pos += l_item_size;
+                                    l_item_idx++;
+                                }
+                            }
+                        }
+                        DAP_DEL_Z(l_datums);
+                        // go to next atom
+                        l_atom = l_chain->callback_atom_iter_get_next(l_atom_iter, &l_atom_size);
+
+                    }
+                }
+            }
+        } break;
+
+    }
+    return l_ret;
+
+}
+
+/**
+ * @brief dap_chain_datum_tx_spends_items_free
+ * @param a_items
+ */
+void dap_chain_datum_tx_spends_items_free(dap_chain_datum_tx_spends_items_t * a_items)
+{
+    assert(a_items);
+    dap_chain_datum_tx_spends_item_free(a_items->tx_ins);
+    dap_chain_datum_tx_spends_item_free(a_items->tx_outs);
+    DAP_DELETE(a_items);
+}
+
+/**
+ * @brief dap_chain_datum_tx_spends_item_free
+ * @param a_items
+ */
+void dap_chain_datum_tx_spends_item_free(dap_chain_datum_tx_spends_item_t * a_items)
+{
+    dap_chain_datum_tx_spends_item_t * l_item, *l_tmp;
+    HASH_ITER(hh,a_items,l_item,l_tmp){
+        DAP_DELETE(l_item->tx);
+        HASH_DELETE(hh,a_items, l_item);
+        DAP_DELETE(l_item);
+    }
+}
+
 /**
  * @brief dap_chain_net_get_tx_cond_all_by_srv_uid
  * @param a_net
@@ -3635,9 +3794,7 @@ dap_list_t* dap_chain_datum_list(dap_chain_net_t *a_net, dap_chain_t *a_chain, d
     dap_list_t *l_list = NULL;
     if(!a_net)
         return l_list;
-    //dap_ledger_t *l_ledger = a_net->pub.ledger;
     void *l_chain_tmp = (void*) 0x1;
-    int l_num = 0;
     dap_chain_t *l_chain_cur;
     if(a_chain)
         l_chain_cur = a_chain;
@@ -3679,3 +3836,81 @@ dap_list_t* dap_chain_datum_list(dap_chain_net_t *a_net, dap_chain_t *a_chain, d
     }
     return l_list;
 }
+
+/**
+ * @brief Add datum to the ledger or smth else
+ * @param a_chain
+ * @param a_datum
+ * @param a_datum_size
+ * @return
+ */
+int dap_chain_datum_add(dap_chain_t * a_chain, dap_chain_datum_t *a_datum, size_t a_datum_size  )
+{
+    size_t l_datum_data_size = a_datum->header.data_size;
+    if ( a_datum_size < l_datum_data_size+ sizeof (a_datum->header) ){
+        log_it(L_INFO,"Corrupted datum rejected: wrong size %zd not equel or less datum size %zd",a_datum->header.data_size+ sizeof (a_datum->header),
+               a_datum_size );
+        return -1;
+    }
+    switch (a_datum->header.type_id) {
+        case DAP_CHAIN_DATUM_DECREE:{
+            dap_chain_datum_decree_t * l_decree = (dap_chain_datum_decree_t *) a_datum->data;
+            if( sizeof(l_decree->header)> l_datum_data_size  ){
+                log_it(L_WARNING, "Corrupted decree, size %zd is smaller than ever decree header's size %zd", l_datum_data_size,
+                       sizeof(l_decree->header));
+                break;
+            }
+
+
+            switch(l_decree->header.type){
+                case DAP_CHAIN_DATUM_DECREE_TYPE_SERVICE:{
+                    dap_chain_net_srv_t * l_srv = dap_chain_net_srv_get(l_decree->header.srv_id);
+                    if(l_srv){
+                        if(l_srv->callbacks.decree){
+                            dap_chain_net_t * l_net = dap_chain_net_by_id(a_chain->net_id);
+                            l_srv->callbacks.decree(l_srv,l_net,a_chain,l_decree,l_datum_data_size);
+                         }
+                    }else{
+                        log_it(L_WARNING,"Decree for unknown srv uid 0x%016"DAP_UINT64_FORMAT_X , l_decree->header.srv_id.uint64);
+                    }
+                }break;
+                default:;
+            }
+        }break;
+
+        case DAP_CHAIN_DATUM_TOKEN_DECL:{
+            if (dap_chain_ledger_token_load(a_chain->ledger, (dap_chain_datum_token_t *)a_datum->data, a_datum->header.data_size))
+                return -2;
+        }break;
+        case DAP_CHAIN_DATUM_TOKEN_EMISSION: {
+            if (dap_chain_ledger_token_emission_load(a_chain->ledger, a_datum->data, a_datum->header.data_size))
+                return -3;
+        }break;
+        case DAP_CHAIN_DATUM_TX:{
+            dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*) a_datum->data;
+            // Check tx correcntess
+            size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx);
+            if (l_tx_size > l_datum_data_size  ){
+                log_it(L_WARNING, "Corrupted transaction in datum, size %zd is greater than datum's size %zd", l_tx_size, l_datum_data_size);
+                return -1;
+            }
+
+            // TODO process with different codes from ledger to work with ledger thresholds
+            if (dap_chain_ledger_tx_load(a_chain->ledger, l_tx, NULL) != 1)
+                return -4;
+        }break;
+        case DAP_CHAIN_DATUM_CA:{
+
+            if ( dap_cert_chain_file_save(a_datum, a_chain->net_name) < 0 )
+                return -5;
+        }break;
+        case DAP_CHAIN_DATUM_SIGNER:
+        break;
+        case DAP_CHAIN_DATUM_CUSTOM:
+        break;
+        default:
+            return -666;
+    }
+    return 0;
+}
+
diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c
index 84e4c29a4f16619b857904c8d4e5f9f00034b5fa..74312a096ad4a21a00653d361d98ca6c384e3cf0 100644
--- a/modules/net/dap_chain_node_cli_cmd.c
+++ b/modules/net/dap_chain_node_cli_cmd.c
@@ -2027,15 +2027,21 @@ int dap_chain_node_cli_cmd_values_parse_net_chain(int *a_arg_index, int argc, ch
                 return -103;
             }
         }
-        else if ((*a_chain = dap_chain_net_get_default_chain_by_chain_type(*a_net, CHAIN_TYPE_TOKEN)) == NULL) {
-				dap_chain_node_cli_set_reply_text(a_str_reply,
-												  "%s requires parameter '-chain' or set default datum type in chain configuration file",
-												  argv[0]);
-				return -104;
+        else if (	!strcmp(argv[0], "token_decl")
+        ||			!strcmp(argv[0], "token_decl_sign")) {
+            if (	(*a_chain = dap_chain_net_get_default_chain_by_chain_type(*a_net, CHAIN_TYPE_TOKEN)) == NULL )
+            {
+                dap_chain_node_cli_set_reply_text(a_str_reply,
+                                                  "%s requires parameter '-chain' or set default datum type in chain configuration file",
+                                                  argv[0]);
+                return -104;
+            }
+        } else {
+            dap_chain_node_cli_set_reply_text(a_str_reply, "%s requires parameter '-chain'", argv[0]);
+            return -104;
         }
     }
     return 0;
-
 }
 
 /**
diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h
index 88de1af22715dafacd8f380b7cd97e479b470181..5dee1800032bb6a3f0c21ba8b11df3e2316b63cd 100644
--- a/modules/net/include/dap_chain_net.h
+++ b/modules/net/include/dap_chain_net.h
@@ -27,9 +27,9 @@ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/lic
 
 #include <stdint.h>
 #include <string.h>
-#include "dap_chain_datum_tx.h"
-#include "dap_math_ops.h"
 #include "dap_net.h"
+#include "dap_time.h"
+#include "dap_math_ops.h"
 #include "dap_stream_ch.h"
 #include "dap_strfuncs.h"
 #include "dap_string.h"
@@ -38,7 +38,7 @@ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/lic
 #include "dap_chain_node.h"
 #include "dap_chain.h"
 #include "dap_chain_ledger.h"
-#include "dap_time.h"
+#include "dap_chain_datum_tx.h"
 #include "uthash.h"
 
 
diff --git a/modules/net/srv/CMakeLists.txt b/modules/net/srv/CMakeLists.txt
index 505a2deb8bc6634dccf8969c98e201485493d885..aaa29abbe4d1fd6080ef7ac917095b819e1f9c9c 100644
--- a/modules/net/srv/CMakeLists.txt
+++ b/modules/net/srv/CMakeLists.txt
@@ -13,10 +13,6 @@ if (CELLFRAME_MODULES MATCHES "modules-dynamic")
     set(NET_SRV_LIBS ${NET_SRV_LIBS} dap_modules_dynamic_cdb)
 endif()
 
-#if (CELLFRAME_MODULES MATCHES "srv-stake")
-#    set(NET_SRV_LIBS ${NET_SRV_LIBS} dap_chain_net_srv_stake)
-#endif()
-
 target_link_libraries(${NET_SRV_LIBS})
 target_include_directories(${PROJECT_NAME} INTERFACE .)
 target_include_directories(${PROJECT_NAME} PUBLIC include)
diff --git a/modules/net/srv/include/dap_chain_net_srv.h b/modules/net/srv/include/dap_chain_net_srv.h
index 302780c367390ab04f3bb3a0f43c77e1aa0b660e..5f9686769e42ab884e7c97ee590c26af95a713be 100755
--- a/modules/net/srv/include/dap_chain_net_srv.h
+++ b/modules/net/srv/include/dap_chain_net_srv.h
@@ -24,9 +24,9 @@ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/lic
 */
 #pragma once
 
+#include "dap_chain_net.h"
 #include "dap_chain_common.h"
 #include "dap_chain_datum_decree.h"
-#include "dap_chain_net.h"
 #include "dap_chain_net_remote.h"
 #include "dap_chain_wallet.h"
 #include "dap_common.h"
diff --git a/modules/service/stake_pos_delegate/dap_chain_net_srv_stake_pos_delegate.c b/modules/service/stake_pos_delegate/dap_chain_net_srv_stake_pos_delegate.c
index b55d6f01fdaa229428a93cf7b7789ff852d64bc4..ed81e6a4b094e1d15074746f7398a6be427fda3c 100644
--- a/modules/service/stake_pos_delegate/dap_chain_net_srv_stake_pos_delegate.c
+++ b/modules/service/stake_pos_delegate/dap_chain_net_srv_stake_pos_delegate.c
@@ -257,7 +257,7 @@ static bool s_stake_conditions_calc(dap_chain_tx_out_cond_t *a_cond, dap_chain_d
     return false;
 }
 
-bool dap_chain_net_srv_stake_pos_delegate_verificator(dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx, bool a_owner)
+bool dap_chain_net_srv_stake_pos_delegate_verificator(dap_ledger_t* a_ledger, dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx, bool a_owner)
 {
     if (!s_srv_stake) {
         return false;
diff --git a/modules/service/stake_pos_delegate/include/dap_chain_net_srv_stake_pos_delegate.h b/modules/service/stake_pos_delegate/include/dap_chain_net_srv_stake_pos_delegate.h
index 232d61a436c92def60c44dec266db33f0344173c..69ecdce4f2980ef04e6c5230d9641e7c5a4ba040 100644
--- a/modules/service/stake_pos_delegate/include/dap_chain_net_srv_stake_pos_delegate.h
+++ b/modules/service/stake_pos_delegate/include/dap_chain_net_srv_stake_pos_delegate.h
@@ -57,7 +57,7 @@ typedef struct dap_chain_net_srv_stake {
 
 int dap_chain_net_srv_stake_pos_delegate_init();
 void dap_chain_net_srv_stake_pos_delegate_deinit();
-bool dap_chain_net_srv_stake_pos_delegate_verificator(dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx, bool a_owner);
+bool dap_chain_net_srv_stake_pos_delegate_verificator(dap_ledger_t* a_ledger, dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx, bool a_owner);
 bool dap_chain_net_srv_stake_updater(dap_ledger_t* a_ledger, dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx, bool a_owner);
 bool dap_chain_net_srv_stake_validator(dap_chain_addr_t *a_addr, dap_chain_datum_t *a_datum);
 bool dap_chain_net_srv_stake_key_delegated(dap_chain_addr_t *a_addr);
diff --git a/modules/service/vpn/dap_chain_net_srv_vpn.c b/modules/service/vpn/dap_chain_net_srv_vpn.c
index 16906bf4e03fd3e78e861f10dd8cdaab272e1ce8..b72d9856589bcd3675ec7176b401cc5632029260 100644
--- a/modules/service/vpn/dap_chain_net_srv_vpn.c
+++ b/modules/service/vpn/dap_chain_net_srv_vpn.c
@@ -298,7 +298,7 @@ static bool s_tun_client_send_data(dap_chain_net_srv_ch_vpn_info_t * l_ch_vpn_in
     l_in_daddr.s_addr = ((dap_os_iphdr_t* ) l_pkt_out->data)->ip_dst.s_addr;
 #endif
     if(l_ch_vpn_info->is_on_this_worker){
-        dap_events_socket_t* l_es = dap_worker_esocket_find_uuid(l_ch_vpn_info->worker, l_ch_vpn_info->esocket_uuid);
+        dap_events_socket_t* l_es = dap_context_find(l_ch_vpn_info->worker->context, l_ch_vpn_info->esocket_uuid);
         if (!l_es) {
             log_it(L_ERROR, "No esocket %p on worker #%u, lost %zd data", l_ch_vpn_info->esocket, l_ch_vpn_info->worker->id, a_data_size);
             return false;
@@ -444,7 +444,7 @@ static void s_tun_recv_msg_callback(dap_events_socket_t * a_esocket_queue, void
         }break; /* l_msg->type == TUN_SOCKET_MSG_IP_UNASSIGNED */
 
         case TUN_SOCKET_MSG_CH_VPN_SEND: {
-            if (dap_worker_esocket_find_uuid(a_esocket_queue->worker, l_msg->esocket_uuid) == l_msg->esocket) {
+            if (dap_context_find(a_esocket_queue->worker->context, l_msg->esocket_uuid) == l_msg->esocket) {
                 s_tun_client_send_data_unsafe(l_msg->ch_vpn, l_msg->ch_vpn_send.pkt);
                 if (s_debug_more) {
                     char l_addrbuf[INET_ADDRSTRLEN];
@@ -999,7 +999,7 @@ static void s_ch_vpn_esocket_assigned(dap_events_socket_t *a_es, dap_worker_t *a
         return;
     dap_chain_net_srv_ch_vpn_t * l_ch_vpn = CH_VPN(l_ch);
     assert(l_ch_vpn);
-    s_tun_send_msg_esocket_reasigned_all_inter(a_worker->id, l_ch_vpn, l_ch_vpn->ch->stream->esocket,
+    s_tun_send_msg_esocket_reassigned_all_inter(a_worker->id, l_ch_vpn, l_ch_vpn->ch->stream->esocket,
                                                l_ch_vpn->ch->stream->esocket_uuid, l_ch_vpn->addr_ipv4);
 }
 
@@ -1012,7 +1012,7 @@ static void s_ch_vpn_esocket_unassigned(dap_events_socket_t* a_es, dap_worker_t
    //dap_chain_net_srv_ch_vpn_info_t * l_info = NULL;
    // HASH_FIND(hh,l_tun_sock->clients,&l_ch_vpn->addr_ipv4 , sizeof (l_ch_vpn->addr_ipv4), l_info);
 
-    s_tun_send_msg_esocket_reasigned_all_inter(a_es->context->worker->id, l_ch_vpn, l_ch_vpn->ch->stream->esocket,
+    s_tun_send_msg_esocket_reassigned_all_inter(a_es->context->worker->id, l_ch_vpn, l_ch_vpn->ch->stream->esocket,
                                                l_ch_vpn->ch->stream->esocket_uuid, l_ch_vpn->addr_ipv4);
 }
 
@@ -1567,6 +1567,74 @@ static void s_es_tun_delete(dap_events_socket_t * a_es, void * arg)
     }
 }
 
+/**
+ * @brief s_es_tun_write
+ * @param a_es
+ * @param arg
+ */
+static void s_es_tun_write(dap_events_socket_t *a_es, void *arg)
+{
+    (void) arg;
+    dap_chain_net_srv_vpn_tun_socket_t *l_tun = CH_SF_TUN_SOCKET(a_es);
+    assert(l_tun);
+    assert(l_tun->es == a_es);
+    size_t l_shift = 0;
+    debug_if(s_debug_more, L_DEBUG, "Write %lu bytes to tun", l_tun->es->buf_out_size);
+    for (ssize_t l_pkt_size = 0, l_bytes_written = 0; l_tun->es->buf_out_size; ) {
+        ch_vpn_pkt_t *l_vpn_pkt = (ch_vpn_pkt_t *)(l_tun->es->buf_out + l_shift);
+        l_pkt_size = l_vpn_pkt->header.op_data.data_size;
+        debug_if(s_debug_more, L_DEBUG, "Packet: op_code 0x%02x, data size %ld",
+                 l_vpn_pkt->header.op_code, l_pkt_size);
+        l_bytes_written = write(l_tun->es->fd, l_vpn_pkt->data, l_pkt_size);
+        if (l_bytes_written == l_pkt_size) {
+            l_pkt_size += sizeof(l_vpn_pkt->header);
+            l_tun->es->buf_out_size -= l_pkt_size;
+            l_shift += l_pkt_size;
+        } else {
+            int l_errno = errno;
+            debug_if(l_bytes_written > 0, L_WARNING, /* How on earth can this be?... */
+                     "Error on writing to tun: wrote %zd / %zd bytes", l_bytes_written, l_pkt_size);
+            switch (l_errno) {
+            case EAGAIN:
+                /* Unwritten packets remain untouched in da buffa */
+                break;
+            case EINVAL:
+                /* Something wrong with this packet... Doomp eet */
+                debug_if(s_debug_more, L_ERROR, "Skip this packet...");
+                l_pkt_size += sizeof(l_vpn_pkt->header);
+                l_tun->es->buf_out_size -= l_pkt_size;
+                l_shift += l_pkt_size;
+                break;
+            default: {
+                char l_errbuf[128];
+                strerror_r(l_errno, l_errbuf, sizeof(l_errbuf));
+                log_it(L_ERROR, "Error on writing to tun: \"%s\" code %d", l_errbuf, errno);
+                break;
+            }}
+            break; // Finish the buffer processing immediately
+        }
+    }
+    if (l_tun->es->buf_out_size) {
+        debug_if(s_debug_more, L_DEBUG, "Left %lu bytes unwritten", l_tun->es->buf_out_size);
+        if (l_shift)
+            memmove(l_tun->es->buf_out, &l_tun->es->buf_out[l_shift], l_tun->es->buf_out_size);
+    }
+    l_tun->buf_size_aux = l_tun->es->buf_out_size;  /* We backup the genuine buffer size... */
+    l_tun->es->buf_out_size = 0;                    /* ... and insure the socket against coursing thru regular writing operations */
+}
+
+static void s_es_tun_write_finished(dap_events_socket_t *a_es, void *a_arg, int a_errno) {
+    UNUSED(a_arg);
+    UNUSED(a_errno);
+    dap_chain_net_srv_vpn_tun_socket_t *l_tun = CH_SF_TUN_SOCKET(a_es);
+    assert(l_tun);
+    assert(l_tun->es == a_es);
+    l_tun->es->buf_out_size = l_tun->buf_size_aux; /* Backup the genuine buffer size */
+    dap_events_socket_set_writable_unsafe(a_es, l_tun->buf_size_aux > 0);
+    debug_if(s_debug_more && (l_tun->buf_size_aux > 0), L_INFO, "%zd bytes still in buf_out, poll again", l_tun->buf_size_aux);
+    l_tun->buf_size_aux = 0;
+}
+
 /**
  * @brief s_es_tun_read
  * @param a_es
diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 70fde650139506fb9871dbec7dd61ce5a541a0b9..701718d563229263fcee33d590779c0b049ce202 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -24,11 +24,11 @@
 
 #include <math.h>
 #include <pthread.h>
+#include "dap_chain_net.h"
 #include "dap_chain_datum_tx.h"
 #include "dap_time.h"
 #include "dap_chain_net_srv.h"
 #include "dap_chain_ledger.h"
-#include "dap_chain_net.h"
 #include "dap_chain_node_cli.h"
 #include "dap_common.h"
 #include "dap_hash.h"
@@ -729,7 +729,7 @@ static int s_cli_srv_xchange_order(int a_argc, char** a_argv, int a_arg_index, c
             dap_chain_hash_fast_from_str(l_order_hash_str, &l_price->order_hash);
             if (!s_xchange_tx_put(l_tx, l_net)) {
                 dap_chain_node_cli_set_reply_text(a_str_reply, "Can't put transaction to mempool");
-                dap_chain_net_srv_order_delete_by_hash_str(l_net, l_order_hash_str);
+                dap_chain_net_srv_order_delete_by_hash_str_sync(l_net, l_order_hash_str);
                 DAP_DELETE(l_order_hash_str);
                 DAP_DELETE(l_price->wallet_str);
                 DAP_DELETE(l_price);
@@ -852,7 +852,7 @@ static int s_cli_srv_xchange_order(int a_argc, char** a_argv, int a_arg_index, c
                 DAP_DELETE(l_tx_hash_str);
             }
             char* l_order_hash_str = dap_chain_hash_fast_to_str_new(&l_price->order_hash);
-            if (dap_chain_net_srv_order_delete_by_hash_str(l_price->net, l_order_hash_str)) {
+            if (dap_chain_net_srv_order_delete_by_hash_str_sync(l_price->net, l_order_hash_str)) {
                 dap_string_append_printf(l_str_reply, "Can't remove order %s\n", l_order_hash_str);
             }
             DAP_DELETE(l_order_hash_str);
@@ -928,14 +928,14 @@ static int s_cli_srv_xchange_order(int a_argc, char** a_argv, int a_arg_index, c
             }
             // Update the order
             char* l_order_hash_str = dap_chain_hash_fast_to_str_new(&l_price->order_hash);
-            dap_chain_net_srv_order_delete_by_hash_str(l_price->net, l_order_hash_str);
+            dap_chain_net_srv_order_delete_by_hash_str_sync(l_price->net, l_order_hash_str);
             DAP_DELETE(l_order_hash_str);
             l_order_hash_str = s_xchange_order_create(l_price, l_tx);
             if (l_order_hash_str) {
                 dap_chain_hash_fast_from_str(l_order_hash_str, &l_price->order_hash);
                 if (!s_xchange_tx_put(l_tx, l_net)) {
                     dap_chain_node_cli_set_reply_text(a_str_reply, "Can't put transaction to mempool");
-                    dap_chain_net_srv_order_delete_by_hash_str(l_net, l_order_hash_str);
+                    dap_chain_net_srv_order_delete_by_hash_str_sync(l_net, l_order_hash_str);
                     DAP_DELETE(l_order_hash_str);
                     return -15;
                 }
@@ -1214,7 +1214,7 @@ static int s_cli_srv_xchange(int a_argc, char** a_argv, char** a_str_reply)
         char* l_gdb_group_str = dap_chain_net_srv_order_get_gdb_group(l_net);
 
         size_t l_orders_count = 0;
-        dap_global_db_obj_t* l_orders = dap_chain_global_db_gr_load(l_gdb_group_str, &l_orders_count);
+        dap_global_db_obj_t *l_orders = dap_global_db_get_all_sync(l_gdb_group_str, &l_orders_count);
         dap_chain_net_srv_xchange_price_t* l_price;
         dap_string_t* l_reply_str = dap_string_new("");
 
@@ -1249,7 +1249,7 @@ static int s_cli_srv_xchange(int a_argc, char** a_argv, char** a_str_reply)
             DAP_DEL_Z(l_cp3);
             DAP_DEL_Z(l_price);
         }
-        dap_chain_global_db_objs_delete(l_orders, l_orders_count);
+        dap_global_db_objs_delete(l_orders, l_orders_count);
         DAP_DELETE(l_gdb_group_str);
         if (!l_reply_str->len) {
             dap_string_append(l_reply_str, "No orders found");
@@ -1307,7 +1307,7 @@ static int s_cli_srv_xchange(int a_argc, char** a_argv, char** a_str_reply)
             dap_chain_datum_tx_t* l_tx = s_xchange_tx_create_exchange(l_price, l_wallet, l_datoshi_buy);
             if (l_tx && s_xchange_tx_put(l_tx, l_net)) {
                 // TODO send request to seller to update / delete order & price
-                dap_chain_net_srv_order_delete_by_hash_str(l_price->net, l_order_hash_str);
+                dap_chain_net_srv_order_delete_by_hash_str_sync(l_price->net, l_order_hash_str);
             }
             DAP_DELETE(l_price);
             DAP_DELETE(l_order);
@@ -1725,7 +1725,7 @@ static int s_cli_srv_xchange(int a_argc, char** a_argv, char** a_str_reply)
                 dap_string_t* l_reply_str = dap_string_new("");
                 char** l_tickers = NULL;
                 size_t l_tickers_count = 0;
-                dap_chain_ledger_addr_get_token_ticker_all_fast(l_net->pub.ledger, NULL, &l_tickers, &l_tickers_count);
+                dap_chain_ledger_addr_get_token_ticker_all(l_net->pub.ledger, NULL, &l_tickers, &l_tickers_count);
 
                 size_t l_pairs_count = 0;
                 if (l_tickers) {
diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c
index 93f3ac209ca92ffa91ce4b1168166eeb2091478d..53fffa3538ca807619e32664c85ec7d01daecee7 100644
--- a/modules/type/dag/dap_chain_cs_dag.c
+++ b/modules/type/dag/dap_chain_cs_dag.c
@@ -67,18 +67,12 @@ typedef struct dap_chain_cs_dag_event_item {
 
 
 typedef struct dap_chain_cs_dag_pvt {
-    dap_enc_key_t* datum_add_sign_key;
-
-
     pthread_rwlock_t events_rwlock;
-
     dap_chain_cs_dag_event_item_t * events;
-
     dap_chain_cs_dag_event_item_t * tx_events;
     dap_chain_cs_dag_event_item_t * events_treshold;
     dap_chain_cs_dag_event_item_t * events_treshold_conflicted;
     dap_chain_cs_dag_event_item_t * events_lasts_unlinked;
-
 } dap_chain_cs_dag_pvt_t;
 
 #define PVT(a) ((dap_chain_cs_dag_pvt_t *) a->_pvt )
@@ -289,11 +283,10 @@ int dap_chain_cs_dag_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg)
     byte_t *l_current_round = dap_global_db_get_sync(l_gdb_group, DAG_ROUND_CURRENT_KEY, NULL, NULL, NULL);
     l_dag->round_current = l_current_round? *(uint64_t *)l_current_round : 0;
     DAP_DELETE(l_current_round);
-    if ( l_dag->is_single_line ) {
+    if (l_dag->is_single_line)
         log_it (L_NOTICE, "DAG chain initialized (single line)");
-    } else {
+    else
         log_it (L_NOTICE, "DAG chain initialized (multichain)");
-    }
 
     return 0;
 }
@@ -471,7 +464,7 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_add(dap_chain_t * a_cha
         break;
     }
 
-    if (l_event->header.round_id)
+    if (l_event->header.round_id && l_event->header.round_id < UINT_MAX)
         l_dag->round_completed = l_event->header.round_id;
 
     switch (ret) {
@@ -532,7 +525,6 @@ static dap_chain_atom_ptr_t s_chain_callback_atom_add_from_treshold(dap_chain_t
 {
     dap_chain_cs_dag_t * l_dag = DAP_CHAIN_CS_DAG(a_chain);
     dap_chain_cs_dag_event_item_t *l_item = dap_chain_cs_dag_proc_treshold(l_dag, a_chain->ledger);
-//    dap_chain_cs_dag_event_calc_size()
     if(l_item) {
         if(a_event_size_out)
             *a_event_size_out = l_item->event_size;
@@ -633,51 +625,50 @@ static bool s_chain_callback_datums_pool_proc(dap_chain_t * a_chain, dap_chain_d
     if (l_hashes_linked || s_seed_mode ) {
         dap_chain_cs_dag_event_t * l_event = NULL;
         size_t l_event_size = 0;
-        if(l_dag->callback_cs_event_create)
+        byte_t *l_current_round = dap_global_db_get_sync(l_dag->gdb_group_events_round_new, DAG_ROUND_CURRENT_KEY, NULL, NULL, NULL);
+        l_dag->round_current = l_current_round ? *(uint64_t *)l_current_round : 0;
+        DAP_DELETE(l_current_round);
+        if (l_dag->round_current < l_dag->round_completed)
+            l_dag->round_current = l_dag->round_completed;
+        uint64_t l_round_current = ++l_dag->round_current;
+        if (l_dag->callback_cs_event_create)
             l_event = l_dag->callback_cs_event_create(l_dag, a_datum, l_hashes, l_hashes_linked, &l_event_size);
         DAP_DELETE(l_hashes);
         if (l_event && l_event_size) { // Event is created
             if (l_dag->is_add_directly) {
                 l_cell = a_chain->cells;
                 if (s_chain_callback_atom_add(a_chain, l_event, l_event_size) == ATOM_ACCEPT) {
-                    if (dap_chain_atom_save(a_chain, (uint8_t *)l_event, l_event_size, a_chain->cells->id) < 0) {
+                    if (dap_chain_atom_save(a_chain, (uint8_t *)l_event, l_event_size, a_chain->cells->id) < 0)
                         log_it(L_ERROR, "Can't add new event to the file");
-                    }
                 } else {
                     log_it(L_ERROR, "Can't add new event");
                     return false;
                 }
             } else {    // add to new round into global_db
-                uint64_t l_round_current = l_event->header.round_id = ++l_dag->round_current;
                 dap_global_db_set(l_dag->gdb_group_events_round_new, DAG_ROUND_CURRENT_KEY,
                                   &l_round_current, sizeof(uint64_t), false, NULL, NULL);
                 dap_chain_hash_fast_t l_event_hash, l_datum_hash;
+                dap_chain_cs_dag_event_round_item_t *l_round_item =
+                            DAP_NEW_Z_SIZE(dap_chain_cs_dag_event_round_item_t,
+                                            sizeof(dap_chain_cs_dag_event_round_item_t));
+                memcpy(&l_round_item->round_info.datum_hash, &l_datum_hash, sizeof(dap_chain_hash_fast_t));
                 dap_chain_cs_dag_event_calc_hash(l_event,l_event_size, &l_event_hash);
                 char * l_event_hash_str = dap_chain_hash_fast_to_str_new(&l_event_hash);
-                dap_chain_cs_dag_event_round_info_t l_event_round_info = {};
-                // set datum hash for round
-                dap_hash_fast(a_datum, dap_chain_datum_size(a_datum), &l_datum_hash);
-                memcpy(&l_event_round_info.datum_hash, &l_datum_hash, sizeof(dap_chain_hash_fast_t));
-                dap_chain_cs_dag_event_round_item_t * l_round_item =
-                            DAP_NEW_SIZE(dap_chain_cs_dag_event_round_item_t,
-                                            sizeof(dap_chain_cs_dag_event_round_item_t)+l_event_size);
-                memcpy(&l_round_item->round_info, &l_event_round_info, sizeof(dap_chain_cs_dag_event_round_info_t));
-                l_round_item->data_size = l_round_item->event_size = 0;
-
-                if (dap_chain_cs_dag_event_gdb_set(l_dag, l_event_hash_str, l_event, l_event_size, l_round_item)) {
+                bool l_res = dap_chain_cs_dag_event_gdb_set(l_dag, l_event_hash_str, l_event, l_event_size, l_round_item);
+                DAP_DELETE(l_round_item);
+                if (l_res)
                     log_it(L_INFO, "Event %s placed in the new forming round", l_event_hash_str);
-                    DAP_DEL_Z(l_event_hash_str);
-                } else {
+                else
                     log_it(L_ERROR,"Can't add new event to the new events round");
-                    return false;
-                }
+                DAP_DEL_Z(l_event_hash_str);
+                return l_res;
             }
-        }else {
+        } else {
             log_it(L_ERROR,"Can't create new event!");
             return false;
         }
     }
-    return true;
+    return false;
 }
 
 
@@ -1797,9 +1788,7 @@ static int s_cli_dag(int argc, char ** argv, char **a_str_reply)
                         size_t l_event_size_new = dap_chain_cs_dag_event_sign_add(&l_event, l_event_size, l_cert->enc_key);
                         if ( l_event_size_new ) {
                             dap_chain_hash_fast_t l_event_new_hash;
-                            // dap_chain_cs_dag_event_calc_hash(l_event_new, l_event_size_new, &l_event_new_hash);
                             dap_chain_cs_dag_event_calc_hash(l_event, l_event_size_new, &l_event_new_hash);
-                            //size_t l_event_new_size = dap_chain_cs_dag_event_calc_size(l_event_new);
                             char * l_event_new_hash_hex_str = dap_chain_hash_fast_to_str_new(&l_event_new_hash);
                             char * l_event_new_hash_base58_str = NULL;
                             if (dap_strcmp(l_hash_out_type, "hex"))
@@ -1832,6 +1821,7 @@ static int s_cli_dag(int argc, char ** argv, char **a_str_reply)
                                                           l_event_hash_str);
                         ret = -50;
                     }
+                    DAP_DELETE(l_round_item);
                 } else {
                     dap_chain_node_cli_set_reply_text(a_str_reply,
                                                       "Can't find event in round.new - only place where could be signed the new event\n",
diff --git a/modules/type/dag/dap_chain_cs_dag_event.c b/modules/type/dag/dap_chain_cs_dag_event.c
index ba54f1ccbb9f75ade43d3630b99c8ecc6d8d8813..d6720026cd364b4d74839ca8a4146963ae94ae7e 100644
--- a/modules/type/dag/dap_chain_cs_dag_event.c
+++ b/modules/type/dag/dap_chain_cs_dag_event.c
@@ -43,8 +43,9 @@
  * @param a_hashes_count
  * @return
  */
-dap_chain_cs_dag_event_t * dap_chain_cs_dag_event_new(dap_chain_id_t a_chain_id, dap_chain_cell_id_t a_cell_id, dap_chain_datum_t * a_datum,
-                                                      dap_enc_key_t * a_key, dap_chain_hash_fast_t * a_hashes, size_t a_hashes_count, size_t * a_event_size)
+dap_chain_cs_dag_event_t *dap_chain_cs_dag_event_new(dap_chain_id_t a_chain_id, dap_chain_cell_id_t a_cell_id, uint64_t a_round_id,
+                                                     dap_chain_datum_t *a_datum, dap_enc_key_t *a_key,
+                                                     dap_chain_hash_fast_t *a_hashes, size_t a_hashes_count, size_t *a_event_size)
 {
     assert(a_event_size);
     size_t l_hashes_size = sizeof(*a_hashes)*a_hashes_count;
@@ -58,6 +59,7 @@ dap_chain_cs_dag_event_t * dap_chain_cs_dag_event_new(dap_chain_id_t a_chain_id,
     l_event_new->header.cell_id.uint64 = a_cell_id.uint64;
     l_event_new->header.chain_id.uint64 = a_chain_id.uint64;
     l_event_new->header.hash_count = a_hashes_count;
+    l_event_new->header.round_id = a_round_id;
 
     if ( l_hashes_size ){
         memcpy(l_event_new->hashes_n_datum_n_signs, a_hashes, l_hashes_size );
@@ -126,10 +128,7 @@ size_t dap_chain_cs_dag_event_sign_add(dap_chain_cs_dag_event_t **a_event_ptr, s
         log_it(L_DEBUG, "Sign from this key exists: %s", l_hash_str);
         return 0;
     }
-    size_t l_hashes_size = l_event->header.hash_count*sizeof(dap_chain_hash_fast_t);
-    dap_chain_datum_t *l_datum = (dap_chain_datum_t *)(l_event->hashes_n_datum_n_signs + l_hashes_size);
-    size_t l_datum_size =  dap_chain_datum_size(l_datum);
-    size_t l_event_size_excl_sign = sizeof(l_event->header) + l_hashes_size + l_datum_size;
+    size_t l_event_size_excl_sign = dap_chain_cs_dag_event_calc_size_excl_signs(l_event, a_event_size);
     dap_sign_t *l_sign = dap_sign_create(a_key, l_event, l_event_size_excl_sign, 0);
     size_t l_sign_size = dap_sign_get_size(l_sign);
     *a_event_ptr = l_event = DAP_REALLOC(l_event, a_event_size + l_sign_size);
diff --git a/modules/type/dag/include/dap_chain_cs_dag.h b/modules/type/dag/include/dap_chain_cs_dag.h
index 5115eedbfd110b3e8f0d33d2472d8ee574e648b3..84a7dd4ed54f424e3bf3dc649ee367978d9d4832 100644
--- a/modules/type/dag/include/dap_chain_cs_dag.h
+++ b/modules/type/dag/include/dap_chain_cs_dag.h
@@ -26,6 +26,8 @@
 #include "dap_chain.h"
 #include "dap_chain_cs_dag_event.h"
 
+#define DAG_ROUND_CURRENT_KEY "round_current"
+
 typedef struct dap_chain_cs_dag dap_chain_cs_dag_t;
 
 typedef void (*dap_chain_cs_dag_callback_t)(dap_chain_cs_dag_t *);
@@ -82,5 +84,4 @@ void dap_chain_cs_dag_deinit(void);
 int dap_chain_cs_dag_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg);
 void dap_chain_cs_dag_delete(dap_chain_t * a_chain);
 void dap_chain_cs_dag_proc_event_round_new(dap_chain_cs_dag_t *a_dag);
-dap_chain_cs_dag_event_t* dap_chain_cs_dag_find_event_by_hash(dap_chain_cs_dag_t * a_dag,
-                                                              dap_chain_hash_fast_t * a_hash);
+dap_chain_cs_dag_event_t* dap_chain_cs_dag_find_event_by_hash(dap_chain_cs_dag_t * a_dag, dap_chain_hash_fast_t * a_hash);
diff --git a/modules/type/dag/include/dap_chain_cs_dag_event.h b/modules/type/dag/include/dap_chain_cs_dag_event.h
index 7d38eebc78dc5f250cf9afd5fc72b54093b27d7e..20befac788da838b3c2f1057596ec28143ea438b 100644
--- a/modules/type/dag/include/dap_chain_cs_dag_event.h
+++ b/modules/type/dag/include/dap_chain_cs_dag_event.h
@@ -70,10 +70,9 @@ typedef struct dap_chain_cs_dag_event_round_broadcast {
     int attempts;
 } dap_chain_cs_dag_event_round_broadcast_t;
 
-dap_chain_cs_dag_event_t * dap_chain_cs_dag_event_new(dap_chain_id_t a_chain_id, dap_chain_cell_id_t a_cell_id, dap_chain_datum_t * a_datum,
-                                                dap_enc_key_t * a_key,
-                                                dap_chain_hash_fast_t * a_hashes, size_t a_hashes_count, size_t * a_event_size);
-
+dap_chain_cs_dag_event_t *dap_chain_cs_dag_event_new(dap_chain_id_t a_chain_id, dap_chain_cell_id_t a_cell_id, uint64_t a_round_id,
+                                                     dap_chain_datum_t *a_datum, dap_enc_key_t *a_key,
+                                                     dap_chain_hash_fast_t *a_hashes, size_t a_hashes_count, size_t *a_event_size);
 
 /**
  * @brief dap_chain_cs_dag_event_get_datum
@@ -170,6 +169,6 @@ void dap_chain_cs_dag_event_broadcast(dap_chain_cs_dag_t *a_dag, const char a_op
 bool dap_chain_cs_dag_event_gdb_set(dap_chain_cs_dag_t *a_dag, char *a_event_hash_str, dap_chain_cs_dag_event_t *a_event,
                                     size_t a_event_size, dap_chain_cs_dag_event_round_item_t *a_round_item);
 
-dap_chain_cs_dag_event_t* dap_chain_cs_dag_event_gdb_get(const char *a_event_hash_str, size_t *a_event_size,
-                                                        const char *a_group, dap_chain_cs_dag_event_round_info_t * a_event_round_info);
+dap_chain_cs_dag_event_t *dap_chain_cs_dag_event_gdb_get(const char *a_event_hash_str, size_t *a_event_size,
+                                                         const char *a_group, dap_chain_cs_dag_event_round_info_t * a_event_round_info);