diff --git a/modules/consensus/esbocs/dap_chain_cs_esbocs.c b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
index 7569d575a73eae23a3a9d04542fecff8963f4d7a..682642546cb2f1a050e71f16ea7a288b6a08daa8 100644
--- a/modules/consensus/esbocs/dap_chain_cs_esbocs.c
+++ b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
@@ -51,7 +51,7 @@ static void s_callback_delete(dap_chain_cs_blocks_t *a_blocks);
 static int s_callback_created(dap_chain_t *a_chain, dap_config_t *a_chain_net_cfg);
 static size_t s_callback_block_sign(dap_chain_cs_blocks_t *a_blocks, dap_chain_block_t **a_block_ptr, size_t a_block_size);
 static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_block_t *a_block, size_t a_block_size);
-static bool s_callback_get_minimum_fee(dap_chain_t *a_chain, uint256_t l_fee);
+static uint256_t s_callback_get_minimum_fee(dap_chain_t *a_chain);
 static void s_callback_set_min_validators_count(dap_chain_t *a_chain, uint16_t a_new_value);
 
 static int s_cli_esbocs(int argc, char ** argv, char **str_reply);
@@ -287,16 +287,13 @@ static int s_callback_created(dap_chain_t *a_chain, dap_config_t *a_chain_net_cf
     return 0;
 }
 
-static bool s_callback_get_minimum_fee(dap_chain_t *a_chain, uint256_t l_fee)
+static uint256_t s_callback_get_minimum_fee(dap_chain_t *a_chain)
 {
     dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain);
     dap_chain_esbocs_t *l_esbocs = DAP_CHAIN_ESBOCS(l_blocks);
     dap_chain_esbocs_pvt_t *l_esbocs_pvt = PVT(l_esbocs);
 
-    if (compare256(l_fee, l_esbocs_pvt->minimum_fee) < 0)
-        return false;
-
-    return true;
+    return l_esbocs_pvt->minimum_fee;
 }
 
 static void s_callback_delete(dap_chain_cs_blocks_t *a_blocks)
@@ -686,7 +683,19 @@ static void s_session_state_change(dap_chain_esbocs_session_t *a_session, enum s
         }
         l_store->candidate->hdr.meta_n_datum_n_signs_size = l_store->candidate_size - sizeof(l_store->candidate->hdr);
         dap_hash_fast(l_store->candidate, l_store->candidate_size, &l_store->precommit_candidate_hash);
-        // Send PreCommit
+        // Process received earlier PreCommit messages
+        dap_chain_esbocs_message_item_t *l_chain_message, *l_chain_message_tmp;
+        HASH_ITER(hh, a_session->cur_round.message_items, l_chain_message, l_chain_message_tmp) {
+            if (l_chain_message->message->hdr.type == DAP_STREAM_CH_VOTING_MSG_TYPE_PRE_COMMIT &&
+                    dap_hash_fast_compare(&l_chain_message->message->hdr.candidate_hash,
+                                          &a_session->cur_round.attempt_candidate_hash))
+            {
+                dap_chain_esbocs_message_t *l_msg = l_chain_message->message;
+                size_t l_msg_size = sizeof(*l_msg) + l_msg->hdr.sign_size + l_msg->hdr.message_size;
+                s_session_packet_in(a_session, NULL, NULL, &l_chain_message->message_hash, (uint8_t*)l_msg, l_msg_size);
+            }
+        }
+        // Send own PreCommit
         s_message_send(a_session, DAP_STREAM_CH_VOTING_MSG_TYPE_PRE_COMMIT, &l_store->candidate_hash,
                             &l_store->precommit_candidate_hash, sizeof(dap_chain_hash_fast_t),
                                 a_session->cur_round.validators_list);
@@ -1106,15 +1115,20 @@ static void s_session_packet_in(void *a_arg, dap_chain_node_addr_t *a_sender_nod
                  l_message->hdr.type == DAP_STREAM_CH_VOTING_MSG_TYPE_APPROVE);
         if (l_same_type && dap_chain_addr_compare(&l_chain_message->signing_addr, &l_signing_addr) &&
                 dap_hash_fast_compare(&l_chain_message->message->hdr.candidate_hash, &l_message->hdr.candidate_hash)) {
-            debug_if(l_cs_debug, L_MSG, "ESBOCS: net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hu."
-                                        " Message rejected: duplicate message %s",
-                                            l_session->chain->net_name, l_session->chain->name,
-                                                l_session->cur_round.id, l_session->cur_round.attempt_num,
-                                                    s_voting_msg_type_to_str(l_message->hdr.type));
-            goto session_unlock;
+            if (l_message->hdr.type != DAP_STREAM_CH_VOTING_MSG_TYPE_START_SYNC || // Not sync or same sync attempt
+                    *(uint64_t *)l_message_data == *(uint64_t *)l_chain_message->message->msg_n_sign) {
+                debug_if(l_cs_debug, L_MSG, "ESBOCS: net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hu."
+                                            " Message rejected: duplicate message %s",
+                                                l_session->chain->net_name, l_session->chain->name,
+                                                    l_session->cur_round.id, l_session->cur_round.attempt_num,
+                                                        s_voting_msg_type_to_str(l_message->hdr.type));
+                goto session_unlock;
+            }
         }
     }
 
+    s_message_chain_add(l_session, l_message, a_data_size, a_data_hash, &l_signing_addr);
+
     dap_chain_hash_fast_t *l_candidate_hash = &l_message->hdr.candidate_hash;
     switch (l_message->hdr.type) {
     case DAP_STREAM_CH_VOTING_MSG_TYPE_START_SYNC: {
@@ -1157,7 +1171,7 @@ static void s_session_packet_in(void *a_arg, dap_chain_node_addr_t *a_sender_nod
                 break;
             }
         }
-        s_message_chain_add(l_session, l_message, a_data_size, a_data_hash, &l_signing_addr);
+
         for (dap_list_t *it = l_session->cur_round.validators_list; it; it = it->next) {
             dap_chain_esbocs_validator_t *l_validator = it->data;
             if (dap_chain_addr_compare(&l_validator->signing_addr, &l_signing_addr))
@@ -1195,8 +1209,6 @@ static void s_session_packet_in(void *a_arg, dap_chain_node_addr_t *a_sender_nod
             break;
         }
 
-        s_message_chain_add(l_session, l_message, a_data_size, a_data_hash, &l_signing_addr);
-
         if (l_cs_debug) {
             char *l_candidate_hash_str = dap_chain_hash_fast_to_str_new(l_candidate_hash);
             log_it(L_MSG, "ESBOCS: net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hu."
@@ -1246,8 +1258,6 @@ static void s_session_packet_in(void *a_arg, dap_chain_node_addr_t *a_sender_nod
             break;
         }
 
-        s_message_chain_add(l_session, l_message, a_data_size, a_data_hash, &l_signing_addr);
-
         if (l_cs_debug) {
             l_candidate_hash_str = dap_chain_hash_fast_to_str_new(l_candidate_hash);
             log_it(L_MSG, "ESBOCS: net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hu."
@@ -1282,8 +1292,6 @@ static void s_session_packet_in(void *a_arg, dap_chain_node_addr_t *a_sender_nod
             break;
         }
 
-        s_message_chain_add(l_session, l_message, a_data_size, a_data_hash, &l_signing_addr);
-
         if (l_cs_debug) {
             l_candidate_hash_str = dap_chain_hash_fast_to_str_new(l_candidate_hash);
             log_it(L_MSG, "ESBOCS: net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hu."
@@ -1346,7 +1354,6 @@ static void s_session_packet_in(void *a_arg, dap_chain_node_addr_t *a_sender_nod
                                                 l_offset + sizeof(l_store->candidate->hdr)) == 1;
         // check candidate's sign
         if (l_sign_verified) {
-            s_message_chain_add(l_session, l_message, a_data_size, a_data_hash, &l_signing_addr);
             l_store->candidate_signs = dap_list_append(l_store->candidate_signs,
                                                        DAP_DUP_SIZE(l_candidate_sign, l_candidate_sign_size));
             if (dap_list_length(l_store->candidate_signs) == l_round->validators_synced_count) {
@@ -1380,6 +1387,10 @@ static void s_session_packet_in(void *a_arg, dap_chain_node_addr_t *a_sender_nod
             break;
         }
 
+        if (dap_hash_fast_is_blank(&l_store->precommit_candidate_hash))
+            // We have not yet precommit candidate. Message will be processed later
+            break;
+
         dap_hash_fast_t *l_precommit_hash = (dap_hash_fast_t *)l_message_data;
         if (!dap_hash_fast_compare(l_precommit_hash, &l_store->precommit_candidate_hash)) {
             if (l_cs_debug) {
@@ -1399,8 +1410,6 @@ static void s_session_packet_in(void *a_arg, dap_chain_node_addr_t *a_sender_nod
             break;
         }
 
-        s_message_chain_add(l_session, l_message, a_data_size, a_data_hash, &l_signing_addr);
-
         if (l_cs_debug) {
             l_candidate_hash_str = dap_chain_hash_fast_to_str_new(l_candidate_hash);
             log_it(L_MSG, "ESBOCS: net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hu."
diff --git a/modules/net/dap_chain_node.c b/modules/net/dap_chain_node.c
index c87f581212cd20c4c8af62c307b4fc094bddbed7..d1dc0ec17783b9a2360a52fa98e58fd67352aa0e 100644
--- a/modules/net/dap_chain_node.c
+++ b/modules/net/dap_chain_node.c
@@ -254,6 +254,8 @@ void dap_chain_node_mempool_process_all(dap_chain_t *a_chain, bool a_force)
                         char *l_min_fee_str = dap_chain_balance_to_coins(l_min_fee);
                         log_it(L_WARNING, "Fee %s is lower than minimum fee %s for tx %s",
                                l_tx_fee_str, l_min_fee_str, l_objs[i].key);
+                        DAP_DELETE(l_tx_fee_str);
+                        DAP_DELETE(l_min_fee_str);
                         continue;
                     }
                 }
diff --git a/modules/net/srv/dap_chain_net_srv.c b/modules/net/srv/dap_chain_net_srv.c
index 9b919d140689609d4b858fae59eaa42d36eaa093..e05ed4ee42f32bf7dc670693ab0de1a918f0b55c 100644
--- a/modules/net/srv/dap_chain_net_srv.c
+++ b/modules/net/srv/dap_chain_net_srv.c
@@ -605,37 +605,30 @@ static int s_cli_net_srv( int argc, char **argv, char **a_str_reply)
  * @param a_owner
  * @return
  */
-static bool s_fee_verificator_callback(dap_ledger_t * a_ledger, dap_hash_fast_t *a_tx_out_hash,dap_chain_tx_out_cond_t *a_cond,
-                                       dap_chain_datum_tx_t *a_tx_in, bool a_owner)
+static bool s_fee_verificator_callback(dap_ledger_t *a_ledger, UNUSED_ARG dap_hash_fast_t *a_tx_out_hash,
+                                       UNUSED_ARG dap_chain_tx_out_cond_t *a_cond,
+                                       dap_chain_datum_tx_t *a_tx_in, UNUSED_ARG bool a_owner)
 {
-    UNUSED(a_cond);
-    const char * l_net_name     = a_ledger->net_name;
-    dap_sign_t * l_sign_block   = NULL;
-    dap_sign_t * l_sign_tx      = NULL;
-    dap_chain_net_t * l_net     = NULL;
-    dap_chain_t * l_chain       = NULL;
-    dap_chain_datum_tx_t * l_tx = NULL;
-    const dap_chain_block_cache_t *l_block_cache = NULL;
-
-    //UNUSED(a_owner);
-    //if (!a_owner)
-        //return false;
-
-    l_net = l_net_name ? dap_chain_net_by_name(l_net_name) : NULL;
-
-    l_chain = dap_chain_net_get_chain_by_chain_type(l_net, CHAIN_TYPE_CA );
-
-    //l_tx = l_chain->callback_tx_find_by_hash(l_chain, a_tx_out_hash);    
-    l_block_cache = l_chain->callback_block_find_by_tx_hash(l_chain,a_tx_out_hash);
-    l_sign_block = dap_chain_block_sign_get(l_block_cache->block, l_block_cache->block_size, 0);
-    //dap_chain_hash_fast_t l_pkey_hash;
-    //dap_sign_get_pkey_hash(l_sign_block, &l_pkey_hash);
-
-    dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx_in, NULL, TX_ITEM_TYPE_SIG, NULL);
-    l_sign_tx = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_sig);
-
-    return dap_sign_match_pkey_signs(l_sign_block,l_sign_tx);
-
+    dap_chain_net_t *l_net = dap_chain_net_by_name(a_ledger->net_name);
+    if (!l_net)
+        return false;
+    dap_chain_t *l_chain;
+    DL_FOREACH(l_net->pub.chains, l_chain) {
+        if (!l_chain->callback_block_find_by_tx_hash)
+            continue;
+        const dap_chain_block_cache_t *l_block_cache = l_chain->callback_block_find_by_tx_hash(l_chain, a_tx_out_hash);
+        if (!l_block_cache)
+            continue;
+        dap_sign_t *l_sign_block = dap_chain_block_sign_get(l_block_cache->block, l_block_cache->block_size, 0);
+        if (!l_sign_block)
+            return false;
+
+        // TX sign is already verified, just compare pkeys
+        dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx_in, NULL, TX_ITEM_TYPE_SIG, NULL);
+        dap_sign_t *l_sign_tx = dap_chain_datum_tx_item_sign_get_sig(l_tx_sig);
+        return dap_sign_match_pkey_signs(l_sign_block, l_sign_tx);
+    }
+    return false;
 }
 
 /**