From 470483914cdc43981ecd85446170bb12a122d85b Mon Sep 17 00:00:00 2001
From: Olzhas <oljas.jarasbaev@demlabs.net>
Date: Wed, 26 Jun 2024 17:11:41 +0700
Subject: [PATCH] [*] chain download notify

---
 modules/chain/dap_chain.c         | 17 ++++++++++++++++-
 modules/chain/dap_chain_cell.c    |  2 ++
 modules/chain/include/dap_chain.h |  1 +
 modules/net/dap_chain_ledger.c    |  2 +-
 4 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/modules/chain/dap_chain.c b/modules/chain/dap_chain.c
index d1a0d3c461..5c5fdf98f8 100644
--- a/modules/chain/dap_chain.c
+++ b/modules/chain/dap_chain.c
@@ -41,8 +41,10 @@
 #include "dap_cert_file.h"
 #include "dap_chain_ch.h"
 #include "dap_stream_ch_gossip.h"
+#include "dap_notify_srv.h"
 #include <uthash.h>
 #include <pthread.h>
+#include "json.h"
 
 #define LOG_TAG "chain"
 
@@ -110,7 +112,7 @@ dap_chain_t *dap_chain_create(const char *a_chain_net_name, const char *a_chain_
             .net_id     = a_chain_net_id,
             .name       = dap_strdup(a_chain_name),
             .net_name   = dap_strdup(a_chain_net_name),
-            .is_mapped  = dap_config_get_item_bool_default(g_config, "ledger", "mapped", true),
+            .is_mapped  = dap_config_get_item_bool_default(g_config, "ledger", "mapped", false),
             .cell_rwlock    = PTHREAD_RWLOCK_INITIALIZER,
             .atom_notifiers = NULL
     };
@@ -580,6 +582,16 @@ int dap_chain_save_all(dap_chain_t *l_chain)
     return l_ret;
 }
 
+bool download_notify_callback(dap_chain_t* a_chain) {
+    json_object* l_chain_info = json_object_new_object();
+    json_object_object_add(l_chain_info, "net_name", json_object_new_string(a_chain->net_name));
+    json_object_object_add(l_chain_info, "download_percentage", json_object_new_int(a_chain->download_percentage));
+    dap_notify_server_send_mt(l_chain_info);
+    log_it(L_DEBUG, "Download notify: net_name: %s download:%d%c", a_chain->net_name, a_chain->download_percentage, '%');
+    json_object_put(l_chain_info);
+    return true;
+}
+
 /**
  * @brief dap_chain_load_all
  * @param l_chain
@@ -610,6 +622,7 @@ int dap_chain_load_all(dap_chain_t *a_chain)
             uint64_t l_cell_id_uint64 = 0;
             sscanf(l_filename, "%"DAP_UINT64_FORMAT_x".dchaincell", &l_cell_id_uint64);
             dap_chain_cell_t *l_cell = dap_chain_cell_create_fill(a_chain, (dap_chain_cell_id_t){ .uint64 = l_cell_id_uint64 });
+            dap_timerfd_t* l_download_notify_timer = dap_timerfd_start(5000, (dap_timerfd_callback_t)download_notify_callback, a_chain);
             l_ret += dap_chain_cell_load(a_chain, l_cell);
             if ( DAP_CHAIN_PVT(a_chain)->need_reorder ) {
 #ifdef DAP_OS_WINDOWS
@@ -629,6 +642,8 @@ int dap_chain_load_all(dap_chain_t *a_chain)
                 DAP_DELETE(l_filename_backup);
 #endif
             }
+            dap_timerfd_delete_unsafe(l_download_notify_timer);
+            download_notify_callback(a_chain);
         }
     }
     closedir(l_dir);
diff --git a/modules/chain/dap_chain_cell.c b/modules/chain/dap_chain_cell.c
index e72e14f11b..a779539625 100644
--- a/modules/chain/dap_chain_cell.c
+++ b/modules/chain/dap_chain_cell.c
@@ -444,6 +444,7 @@ int dap_chain_cell_load(dap_chain_t *a_chain, dap_chain_cell_t *a_cell)
             if ( space_left < sizeof(uint64_t) || (space_left - sizeof(uint64_t)) < *(uint64_t*)a_cell->map_pos )
                 if ( s_cell_map_new_volume(a_cell, l_pos) )
                     break;
+            a_chain->download_percentage =  (int)((double)l_pos/l_size * 100 + 0.5);
             l_el_size = *(uint64_t*)a_cell->map_pos;
             dap_hash_fast_t l_atom_hash;
             dap_chain_atom_ptr_t l_atom = (dap_chain_atom_ptr_t)(a_cell->map_pos += sizeof(uint64_t));
@@ -468,6 +469,7 @@ int dap_chain_cell_load(dap_chain_t *a_chain, dap_chain_cell_t *a_cell)
                 break;
             }
             l_pos += sizeof(uint64_t) + ( l_read = fread((void*)l_element, 1, l_el_size, a_cell->file_storage) );
+            a_chain->download_percentage =  (int)((double)l_pos/l_size * 100 + 0.5);
             if (l_read != l_el_size) {
                 log_it(L_ERROR, "Read only %lu of %zu bytes, stop cell loading", l_read, l_el_size);
                 DAP_DELETE(l_element);
diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h
index 6d8b28b553..485a61745c 100644
--- a/modules/chain/include/dap_chain.h
+++ b/modules/chain/include/dap_chain.h
@@ -140,6 +140,7 @@ typedef struct dap_chain {
     char *net_name;
     bool is_datum_pool_proc;
     bool is_mapped;
+    size_t download_percentage; 
     // Nested cells (hashtab by cell_id)
     dap_chain_cell_t *cells;
     dap_chain_cell_id_t active_cell_id;
diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c
index 40ccfc136e..bc060b1ca5 100644
--- a/modules/net/dap_chain_ledger.c
+++ b/modules/net/dap_chain_ledger.c
@@ -585,7 +585,7 @@ static dap_ledger_t * dap_ledger_handle_new(void)
                                                                       (dap_timer_callback_t)s_threshold_txs_free, l_ledger);
     l_ledger_pvt->threshold_emissions_free_timer = dap_interval_timer_create(s_threshold_free_timer_tick,
                                                                             (dap_timer_callback_t) s_threshold_emission_free, l_ledger);                                                                          
-    l_ledger_pvt->mapped = dap_config_get_item_bool_default(g_config, "ledger", "mapped", true);
+    l_ledger_pvt->mapped = dap_config_get_item_bool_default(g_config, "ledger", "mapped", false);
     return l_ledger;
 }
 
-- 
GitLab