From f5443ed65d287d797fbd0fae4001f54abe834a40 Mon Sep 17 00:00:00 2001
From: Roman Khlopkov <roman.khlopkov@demlabs.net>
Date: Tue, 16 May 2023 12:36:31 +0300
Subject: [PATCH] [*] Round sync & numbering fixes

---
 .../chain-voting/dap_stream_ch_chain_voting.c |  7 ++++--
 .../consensus/esbocs/dap_chain_cs_esbocs.c    | 23 +++++++++++++------
 .../esbocs/include/dap_chain_cs_esbocs.h      |  1 +
 modules/net/dap_chain_net.c                   |  3 +--
 4 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/modules/channel/chain-voting/dap_stream_ch_chain_voting.c b/modules/channel/chain-voting/dap_stream_ch_chain_voting.c
index 93560ed421..b7dd8dfe92 100644
--- a/modules/channel/chain-voting/dap_stream_ch_chain_voting.c
+++ b/modules/channel/chain-voting/dap_stream_ch_chain_voting.c
@@ -14,6 +14,8 @@
 
 #define LOG_TAG "dap_stream_ch_chain_voting"
 
+#define PKT_SIGN_N_HDR_OVERHEAD (15 * 1024)
+
 struct voting_pkt_in_callback {
     void * arg;
     dap_chain_voting_ch_callback_t packet_in_callback;
@@ -143,8 +145,9 @@ static void s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg)
         return;
 
     size_t l_voting_pkt_size = l_ch_pkt->hdr.data_size;
-    if (!l_voting_pkt_size || l_voting_pkt_size > DAP_CHAIN_CS_BLOCKS_MAX_BLOCK_SIZE + sizeof(dap_stream_ch_chain_voting_pkt_t)) {
-        log_it(L_ERROR, "Maximum packet size exceeded, drop this packet");
+    if (!l_voting_pkt_size || l_voting_pkt_size < sizeof(dap_stream_ch_chain_voting_pkt_t) ||
+            l_voting_pkt_size > DAP_CHAIN_CS_BLOCKS_MAX_BLOCK_SIZE + PKT_SIGN_N_HDR_OVERHEAD) {
+        log_it(L_ERROR, "Invalid packet size %zu, drop this packet", l_voting_pkt_size);
         return;
     }
 
diff --git a/modules/consensus/esbocs/dap_chain_cs_esbocs.c b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
index 7ed1d5599c..8279ac1fb4 100644
--- a/modules/consensus/esbocs/dap_chain_cs_esbocs.c
+++ b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
@@ -483,6 +483,8 @@ static dap_list_t *s_validator_check_synced(dap_chain_addr_t *a_addr, dap_list_t
 
 static void s_session_send_startsync(dap_chain_esbocs_session_t *a_session)
 {
+    if (a_session->cur_round.sync_sent)
+        return;     // Sync message already was sent
     dap_chain_hash_fast_t l_last_block_hash;
     s_get_last_block_hash(a_session->chain, &l_last_block_hash);
     a_session->ts_round_sync_start = dap_time_now();
@@ -497,14 +499,15 @@ static void s_session_send_startsync(dap_chain_esbocs_session_t *a_session)
                                      NODE_ADDR_FP_ARGS_S(((dap_chain_esbocs_validator_t *)it->data)->node_addr));
         }
         log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U"."
-                       " Sent START_SYNC pkt, attempt %"DAP_UINT64_FORMAT_U" current validators list: %s",
+                       " Sent START_SYNC pkt, sync attempt %"DAP_UINT64_FORMAT_U" current validators list: %s",
                             a_session->chain->net_name, a_session->chain->name, a_session->cur_round.id,
                                 a_session->cur_round.sync_attempt, l_addr_list->str);
         dap_string_free(l_addr_list, true);
     }
     s_message_send(a_session, DAP_STREAM_CH_VOTING_MSG_TYPE_START_SYNC, &l_last_block_hash,
-                   & a_session->cur_round.sync_attempt, sizeof(uint64_t),
+                   &a_session->cur_round.sync_attempt, sizeof(uint64_t),
                    a_session->cur_round.validators_list);
+    a_session->cur_round.sync_sent = true;
 }
 
 static bool s_session_send_startsync_on_timer(void *a_arg)
@@ -561,7 +564,8 @@ static void s_session_round_new(dap_chain_esbocs_session_t *a_session)
             (!dap_hash_fast_is_blank(&l_last_block_hash) &&
                 dap_hash_fast_is_blank(&a_session->cur_round.last_block_hash))) {
         a_session->cur_round.last_block_hash = l_last_block_hash;
-        a_session->cur_round.sync_attempt = 1;
+        if (!a_session->round_fast_forward)
+            a_session->cur_round.sync_attempt = 1;
     }
     a_session->cur_round.validators_list = s_get_validators_list(a_session, a_session->cur_round.sync_attempt - 1);
     bool l_round_already_started = a_session->round_fast_forward;
@@ -593,7 +597,7 @@ static void s_session_round_new(dap_chain_esbocs_session_t *a_session)
                     a_session->chain->net_name, a_session->chain->name,
                         a_session->cur_round.id, l_round_already_started ? 0 : PVT(a_session->esbocs)->new_round_delay);
     }
-    if (PVT(a_session->esbocs)->new_round_delay && !l_round_already_started)
+    if (PVT(a_session->esbocs)->new_round_delay && !l_round_already_started && !a_session->cur_round.sync_sent)
         a_session->sync_timer = dap_timerfd_start(PVT(a_session->esbocs)->new_round_delay * 1000,
                                                   s_session_send_startsync_on_timer, a_session);
     else
@@ -623,7 +627,7 @@ static void s_session_attempt_new(dap_chain_esbocs_session_t *a_session)
         }
     }
     debug_if(PVT(a_session->esbocs)->debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U"."
-                                                    " Round finished by reason: all synced validators already tryed its attempt",
+                                                    " Round finished by reason: all synced validators already tryed their attempts",
                                                         a_session->chain->net_name, a_session->chain->name,
                                                             a_session->cur_round.id);
     s_session_round_new(a_session);
@@ -671,7 +675,7 @@ static uint64_t s_session_calc_current_round_id(dap_chain_esbocs_session_t *a_se
         } else if (l_id_candidates[i].counter == l_counter_max) // Choose maximum round ID
             l_ret = MAX(l_ret, l_id_candidates[i].id);
     }
-    return l_ret;
+    return l_ret ? l_ret : a_session->cur_round.id;
 }
 
 static int s_signs_sort_callback(const void *a_sign1, const void *a_sign2, UNUSED_ARG void *a_user_data)
@@ -1308,6 +1312,10 @@ static void s_session_packet_in(void *a_arg, dap_chain_node_addr_t *a_sender_nod
         // consensus round start sync
         if (l_message->hdr.type == DAP_STREAM_CH_VOTING_MSG_TYPE_START_SYNC) {
             if (!dap_hash_fast_compare(&l_message->hdr.candidate_hash, &l_session->cur_round.last_block_hash)) {
+                debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U"."
+                                            " Sync message with different last block hash was added to the queue",
+                                                l_session->chain->net_name, l_session->chain->name,
+                                                    l_session->cur_round.id);
                 s_session_sync_queue_add(l_session, l_message, a_data_size);
                 goto session_unlock;
             }
@@ -1428,7 +1436,8 @@ static void s_session_packet_in(void *a_arg, dap_chain_node_addr_t *a_sender_nod
                 }
             }
             break;
-        }
+        } else // Send it immediatly, if was not sent yet
+            s_session_send_startsync(l_session);
 
         bool l_msg_from_list = false;
         for (dap_list_t *it = l_session->cur_round.validators_list; it; it = it->next) {
diff --git a/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h b/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h
index aa0d39e31b..9a9d55b3e7 100644
--- a/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h
+++ b/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h
@@ -100,6 +100,7 @@ typedef struct dap_chain_esbocs_round {
     uint16_t validators_synced_count;
     dap_list_t *validators_list;
     uint64_t sync_attempt;
+    bool sync_sent;
 } dap_chain_esbocs_round_t;
 
 typedef struct dap_chain_esbocs_validator {
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index e10e6cc409..35a230c7a7 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -1861,8 +1861,7 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply)
             if ( strcmp(l_get_str,"status") == 0 ) {
                 s_set_reply_text_node_status(a_str_reply, l_net);
                 l_ret = 0;
-            }
-            if ( strcmp(l_get_str, "fee") == 0) {
+            } else if ( strcmp(l_get_str, "fee") == 0) {
                 dap_string_t *l_str = dap_string_new("\0");
                 // Network fee
                 uint256_t l_network_fee = {};
-- 
GitLab