From 02fd36f08c6eace9a7388e960ef2f3280135c3c3 Mon Sep 17 00:00:00 2001
From: "roman.khlopkov" <roman.khlopkov@demlabs.net>
Date: Fri, 29 Mar 2024 18:47:12 +0300
Subject: [PATCH] [*] Network denoncation with offline state transition

---
 modules/chain/dap_chain_ch.c                              | 7 +++++++
 modules/chain/include/dap_chain_ch.h                      | 3 ++-
 modules/channel/chain-net/dap_stream_ch_chain_net.c       | 2 +-
 .../channel/chain-net/include/dap_stream_ch_chain_net.h   | 2 +-
 modules/net/dap_chain_net.c                               | 8 ++++++++
 modules/net/dap_chain_node_client.c                       | 2 +-
 .../service/stake/dap_chain_net_srv_stake_pos_delegate.c  | 2 +-
 7 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/modules/chain/dap_chain_ch.c b/modules/chain/dap_chain_ch.c
index d8cb37ec11..f4cfcde1a2 100644
--- a/modules/chain/dap_chain_ch.c
+++ b/modules/chain/dap_chain_ch.c
@@ -900,6 +900,13 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
                     DAP_CHAIN_CH_ERROR_CHAIN_NOT_FOUND);
             break;
         }
+        if (!dap_link_manager_get_net_condition(l_chain_pkt->hdr.net_id.uint64)) {
+            log_it(L_WARNING, "Net id 0x%016" DAP_UINT64_FORMAT_x " is offline", l_chain_pkt->hdr.net_id.uint64);
+            s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
+                    l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
+                    DAP_CHAIN_CH_ERROR_NET_IS_OFFLINE);
+            break;
+        }
         dap_hash_fast_t *l_requested_hash = (dap_hash_fast_t *)l_chain_pkt->data;
         if (dap_hash_fast_is_blank(l_requested_hash))
             l_requested_hash = NULL;
diff --git a/modules/chain/include/dap_chain_ch.h b/modules/chain/include/dap_chain_ch.h
index 010d112b36..13554e358f 100644
--- a/modules/chain/include/dap_chain_ch.h
+++ b/modules/chain/include/dap_chain_ch.h
@@ -55,7 +55,8 @@ typedef enum dap_chain_ch_error_type {
     DAP_CHAIN_CH_ERROR_CHAIN_NOT_FOUND,
     DAP_CHAIN_CH_ERROR_ATOM_NOT_FOUND,
     DAP_CHAIN_CH_ERROR_UNKNOWN_CHAIN_PKT_TYPE,
-    DAP_CHAIN_CH_ERROR_GLOBAL_DB_INTERNAL_NOT_SAVED
+    DAP_CHAIN_CH_ERROR_GLOBAL_DB_INTERNAL_NOT_SAVED,
+    DAP_CHAIN_CH_ERROR_NET_IS_OFFLINE
 } dap_chain_ch_error_type_t;
 
 typedef struct dap_chain_ch dap_chain_ch_t;
diff --git a/modules/channel/chain-net/dap_stream_ch_chain_net.c b/modules/channel/chain-net/dap_stream_ch_chain_net.c
index 44b1a49682..2ec116819d 100644
--- a/modules/channel/chain-net/dap_stream_ch_chain_net.c
+++ b/modules/channel/chain-net/dap_stream_ch_chain_net.c
@@ -68,7 +68,7 @@ static void s_stream_ch_packet_in(dap_stream_ch_t* ch, void* arg);
 int dap_stream_ch_chain_net_init()
 {
     log_it(L_NOTICE, "Chain network channel initialized");
-    dap_stream_ch_proc_add(DAP_STREAM_CH_NET_ID, s_stream_ch_new, s_stream_ch_delete,
+    dap_stream_ch_proc_add(DAP_STREAM_CH_CHAIN_NET_ID, s_stream_ch_new, s_stream_ch_delete,
             s_stream_ch_packet_in, NULL);
 
     return 0;
diff --git a/modules/channel/chain-net/include/dap_stream_ch_chain_net.h b/modules/channel/chain-net/include/dap_stream_ch_chain_net.h
index 181181fe2e..3017b12853 100644
--- a/modules/channel/chain-net/include/dap_stream_ch_chain_net.h
+++ b/modules/channel/chain-net/include/dap_stream_ch_chain_net.h
@@ -61,7 +61,7 @@ typedef struct dap_chain_ch_validator_test{
 #define D_SIGN 0x40//data signed
 #define F_CERT 0x80//faund sert
 
-#define DAP_STREAM_CH_NET_ID 'N'
+#define DAP_STREAM_CH_CHAIN_NET_ID 'N'
 #define DAP_STREAM_CH_CHAIN_NET(a) ((dap_stream_ch_chain_net_t *) ((a)->internal) )
 
 dap_chain_node_addr_t dap_stream_ch_chain_net_from_session_data_extract_node_addr(uint32_t a_session_id);
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index fcef844aa6..2ac0fbd7a7 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -387,6 +387,14 @@ int dap_chain_net_state_go_to(dap_chain_net_t *a_net, dap_chain_net_state_t a_ne
     //PVT(a_net)->flags |= F_DAP_CHAIN_NET_SYNC_FROM_ZERO;  // TODO set this flag according to -mode argument from command line
     PVT(a_net)->state_target = a_new_state;
     if (a_new_state == NET_STATE_OFFLINE) {
+        char l_err_str[] = "ERROR_NET_IS_OFFLINE";
+        dap_stream_ch_chain_net_pkt_t *l_error = DAP_NEW_STACK_SIZE(dap_stream_ch_chain_net_pkt_t,
+                                                                    sizeof(dap_stream_ch_chain_net_pkt_t) + sizeof(l_err_str));
+        l_error->hdr.version = DAP_STREAM_CH_CHAIN_NET_PKT_VERSION;
+        l_error->hdr.net_id = a_net->pub.id;
+        memcpy(l_error->data, l_err_str, sizeof(l_err_str));
+        dap_cluster_broadcast(PVT(a_net)->nodes_cluster->links_cluster, DAP_STREAM_CH_CHAIN_NET_ID,
+                              DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_ERROR, l_error, sizeof(l_error), NULL, 0);
         dap_link_manager_set_net_condition(a_net->pub.id.uint64, false);
         dap_chain_esbocs_stop_timer(a_net->pub.id);
     } else if (PVT(a_net)->state == NET_STATE_OFFLINE) {
diff --git a/modules/net/dap_chain_node_client.c b/modules/net/dap_chain_node_client.c
index 33decfe0cb..37cf0099a0 100644
--- a/modules/net/dap_chain_node_client.c
+++ b/modules/net/dap_chain_node_client.c
@@ -475,7 +475,7 @@ static int s_node_client_set_notify_callbacks(dap_client_t *a_client, uint8_t a_
             l_ret = 0;
             switch (a_ch_id) {
                 //  'N'
-            case DAP_STREAM_CH_NET_ID: {
+            case DAP_STREAM_CH_CHAIN_NET_ID: {
                 dap_stream_ch_chain_net_t *l_ch_chain   = DAP_STREAM_CH_CHAIN_NET(l_ch);
                 l_ch_chain->notify_callback     = s_ch_chain_callback_notify_packet_in2;
                 l_ch_chain->notify_callback_arg = l_node_client;
diff --git a/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c b/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c
index 97d86a325c..1067c0bcf7 100644
--- a/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c
+++ b/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c
@@ -2157,7 +2157,7 @@ int dap_chain_net_srv_stake_check_validator(dap_chain_net_t * a_net, dap_hash_fa
     }
     log_it(L_NOTICE, "Stream connection established");
 
-    uint8_t l_ch_id = DAP_STREAM_CH_NET_ID;
+    uint8_t l_ch_id = DAP_STREAM_CH_CHAIN_NET_ID;
     dap_stream_ch_t * l_ch_chain = dap_client_get_stream_ch_unsafe(l_node_client->client, l_ch_id);
 
     randombytes(l_test_data, sizeof(l_test_data));
-- 
GitLab