From 6ba701c06254ee6af1e29d45f418f07dc1284255 Mon Sep 17 00:00:00 2001
From: "cellframe.docs" <artur.khudiaev@demlabs.net>
Date: Mon, 11 Apr 2022 16:51:19 +0000
Subject: [PATCH] hotfix-5926

---
 dap-sdk/net/core/dap_events.c            |  6 ++-
 modules/chain/dap_chain_ledger.c         | 57 ++++++++++++++++++++++++
 modules/chain/include/dap_chain_ledger.h |  1 +
 modules/net/dap_chain_net.c              | 35 ++++++++++++++-
 modules/net/dap_chain_node_cli.c         |  9 ++--
 modules/net/dap_chain_node_cli_cmd_tx.c  | 38 ++++++++++------
 modules/type/dag/dap_chain_cs_dag.c      |  2 +-
 7 files changed, 127 insertions(+), 21 deletions(-)

diff --git a/dap-sdk/net/core/dap_events.c b/dap-sdk/net/core/dap_events.c
index f49cf96268..d8b32c105b 100644
--- a/dap-sdk/net/core/dap_events.c
+++ b/dap-sdk/net/core/dap_events.c
@@ -207,7 +207,11 @@ void dap_cpu_assign_thread_on(uint32_t a_cpu_id)
  */
 int dap_events_init( uint32_t a_threads_count, size_t a_conn_timeout )
 {
-    s_threads_count = a_threads_count ? a_threads_count : dap_get_cpu_count( );
+    uint32_t l_cpu_count = dap_get_cpu_count();
+    if (a_threads_count > l_cpu_count)
+        a_threads_count = l_cpu_count;
+    
+    s_threads_count = a_threads_count ? a_threads_count : l_cpu_count;
 
     s_workers =  DAP_NEW_Z_SIZE(dap_worker_t*,s_threads_count*sizeof (dap_worker_t*) );
     s_threads = DAP_NEW_Z_SIZE(dap_thread_t, sizeof(dap_thread_t) * s_threads_count );
diff --git a/modules/chain/dap_chain_ledger.c b/modules/chain/dap_chain_ledger.c
index e0fae35e12..18b9562ecc 100644
--- a/modules/chain/dap_chain_ledger.c
+++ b/modules/chain/dap_chain_ledger.c
@@ -907,6 +907,63 @@ int dap_chain_ledger_token_load(dap_ledger_t *a_ledger, dap_chain_datum_token_t
     return dap_chain_ledger_token_add(a_ledger, a_token, a_token_size);
 }
 
+dap_string_t *dap_chain_ledger_treshold_info(dap_ledger_t *a_ledger)
+{
+    dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
+    dap_chain_ledger_tx_item_t *l_tx_item, *l_tx_tmp;
+    dap_string_t *l_str_ret = dap_string_new("");
+    pthread_rwlock_rdlock(&l_ledger_pvt->threshold_txs_rwlock);
+    HASH_ITER(hh, l_ledger_pvt->threshold_txs, l_tx_item, l_tx_tmp){  
+        char l_tx_prev_hash_str[70]={0};
+        char l_time[1024] = {0};
+        char l_item_size[70] = {0};
+        dap_chain_hash_fast_to_str(&l_tx_item->tx_hash_fast,l_tx_prev_hash_str,sizeof(l_tx_prev_hash_str));
+        dap_time_to_str_rfc822(l_time, sizeof(l_time), l_tx_item->tx->header.ts_created);
+        //log_it(L_DEBUG,"Ledger thresholded tx_hash_fast %s, time_created: %s, tx_item_size: %d", l_tx_prev_hash_str, l_time, l_tx_item->tx->header.tx_items_size);
+        dap_string_append(l_str_ret, "Ledger thresholded tx_hash_fast");
+        dap_string_append(l_str_ret, l_tx_prev_hash_str);
+        dap_string_append(l_str_ret, ", time_created:");
+        dap_string_append(l_str_ret, l_time);
+        dap_string_append(l_str_ret, "");
+        sprintf(l_item_size, ", tx_item_size: %d\n", l_tx_item->tx->header.tx_items_size);  
+        dap_string_append(l_str_ret, l_item_size);
+    }
+    pthread_rwlock_unlock(&l_ledger_pvt->threshold_txs_rwlock);
+
+    pthread_rwlock_rdlock(&l_ledger_pvt->threshold_emissions_rwlock);
+    dap_chain_ledger_token_emission_item_t *l_emission_item, *l_emission_tmp;
+    HASH_ITER(hh, l_ledger_pvt->threshold_emissions, l_emission_item, l_emission_tmp){  
+        char l_emission_hash_str[70]={0};
+        char l_item_size[70] = {0};
+        dap_chain_hash_fast_to_str(&l_emission_item->datum_token_emission_hash,l_emission_hash_str,sizeof(l_emission_hash_str));
+       //log_it(L_DEBUG,"Ledger thresholded datum_token_emission_hash %s, emission_item_size: %lld", l_emission_hash_str, l_emission_item->datum_token_emission_size);
+        dap_string_append(l_str_ret, "Ledger thresholded datum_token_emission_hash: ");
+        dap_string_append(l_str_ret, l_emission_hash_str);
+        sprintf(l_item_size, ", tx_item_size: %d\n", l_emission_item->datum_token_emission_size);  
+        dap_string_append(l_str_ret, l_item_size);
+    }
+    pthread_rwlock_unlock(&l_ledger_pvt->threshold_emissions_rwlock);
+
+    pthread_rwlock_rdlock(&l_ledger_pvt->balance_accounts_rwlock);
+    dap_ledger_wallet_balance_t *l_balance_item, *l_balance_tmp;
+    HASH_ITER(hh, l_ledger_pvt->balance_accounts, l_balance_item, l_balance_tmp){  
+        char l_balance_key[70]={0};
+        char l_time[1024] = {0};
+        dap_chain_hash_fast_to_str(&l_balance_item->key,l_balance_key,sizeof(l_balance_key));
+        //log_it(L_DEBUG,"Ledger balance key %s, token_ticker: %s, balance: %s", l_balance_key, l_balance_item->token_ticker, 
+        //                        dap_chain_balance_print(l_balance_item->balance));
+        dap_string_append(l_str_ret, "Ledger balance key: ");
+        dap_string_append(l_str_ret, l_balance_key);
+        dap_string_append(l_str_ret, ", token_ticker:");
+        dap_string_append(l_str_ret, l_balance_item->token_ticker);
+        dap_string_append(l_str_ret, ", balance:");
+        dap_string_append(l_str_ret, dap_chain_balance_print(l_balance_item->balance));
+        dap_string_append(l_str_ret, "\n");
+    }
+    pthread_rwlock_unlock(&l_ledger_pvt->balance_accounts_rwlock);
+    return l_str_ret;
+}
+
 dap_list_t *dap_chain_ledger_token_info(dap_ledger_t *a_ledger)
 {
     dap_list_t *l_ret_list = NULL;
diff --git a/modules/chain/include/dap_chain_ledger.h b/modules/chain/include/dap_chain_ledger.h
index 85a1395502..608c460710 100644
--- a/modules/chain/include/dap_chain_ledger.h
+++ b/modules/chain/include/dap_chain_ledger.h
@@ -126,6 +126,7 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *
 int dap_chain_ledger_token_load(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size);
 int dap_chain_ledger_token_decl_add_check(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token);
 dap_list_t *dap_chain_ledger_token_info(dap_ledger_t *a_ledger);
+dap_string_t *dap_chain_ledger_treshold_info(dap_ledger_t *a_ledger);
 /**
  * Add token emission datum
  */
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index 4e12a0745c..3007093afd 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -502,6 +502,31 @@ static void s_gbd_history_callback_notify(void *a_arg, const char a_op_code, con
     }
 }
 
+static void s_print_workers_channels()
+{
+    uint32_t l_worker_count = dap_events_worker_get_count();
+    dap_stream_ch_t* l_msg_ch = NULL;
+    dap_stream_ch_t* l_msg_ch_tmp = NULL;
+    //print all worker connections
+    dap_events_worker_print_all();
+    for (uint32_t i = 0; i < l_worker_count; i++){
+        uint32_t l_channel_count = 0;
+        dap_worker_t* l_worker = dap_events_worker_get(i);
+        if (!l_worker) {
+            log_it(L_CRITICAL, "Can't get stream worker - worker thread don't exist");
+            continue;
+        }
+        dap_stream_worker_t* l_stream_worker = DAP_STREAM_WORKER(l_worker);
+        if (l_stream_worker->channels)
+            HASH_ITER(hh_worker, l_stream_worker->channels, l_msg_ch, l_msg_ch_tmp) {
+                //log_it(L_DEBUG, "Worker id = %d, channel uuid = 0x%llx", l_worker->id, l_msg_ch->uuid);
+                l_channel_count += 1;
+        }
+        log_it(L_DEBUG, "Active workers l_channel_count = %d on worker %d", l_channel_count, l_stream_worker->worker->id);
+    }
+    return;
+}
+
 /**
  * @brief s_chain_callback_notify
  * @param a_arg
@@ -518,7 +543,13 @@ static void s_chain_callback_notify(void * a_arg, dap_chain_t *a_chain, dap_chai
         for (dap_list_t *l_tmp = PVT(l_net)->net_links; l_tmp; l_tmp = dap_list_next(l_tmp)) {
             dap_chain_node_client_t *l_node_client = ((struct net_link *)l_tmp->data)->link;
             if (l_node_client) {
-                dap_stream_worker_t * l_worker = dap_client_get_stream_worker( l_node_client->client);
+                dap_stream_worker_t * l_worker = dap_client_get_stream_worker(l_node_client->client);
+                if (s_debug_more){
+                    if (!l_worker->channels && l_worker->worker){
+                        log_it(L_WARNING, "Worker id = %d hasn't active channels", l_worker->worker->id);
+                        s_print_workers_channels();
+                    }
+                }
                 if(l_worker)
                     dap_stream_ch_chain_pkt_write_mt(l_worker, l_node_client->ch_chain_uuid, DAP_STREAM_CH_CHAIN_PKT_TYPE_CHAIN,
                                                   l_net->pub.id.uint64, a_chain->id.uint64, a_id.uint64, a_atom, a_atom_size);
@@ -527,7 +558,7 @@ static void s_chain_callback_notify(void * a_arg, dap_chain_t *a_chain, dap_chai
         pthread_rwlock_unlock(&PVT(l_net)->rwlock);
     }else{
         if (s_debug_more)    
-             log_it(L_WARNING,"Node current state is %d. Real-time syncing is possible when you in NET_STATE_LINKS_ESTABLISHED (and above) state", PVT(l_net)->state);     
+             log_it(L_WARNING,"Node current state is %s. Real-time syncing is possible when you in NET_STATE_LINKS_ESTABLISHED (and above) state", s_net_state_to_str(PVT(l_net)->state));     
     }
 }
 
diff --git a/modules/net/dap_chain_node_cli.c b/modules/net/dap_chain_node_cli.c
index 64555d431f..4fa45944fa 100644
--- a/modules/net/dap_chain_node_cli.c
+++ b/modules/net/dap_chain_node_cli.c
@@ -1092,11 +1092,12 @@ int dap_chain_node_cli_init(dap_config_t * g_config)
             "tx_history  [-addr <addr> | -w <wallet name> | -tx <tx_hash>] -net <net name> -chain <chain name>\n");
 
     // Ledger info
-    dap_chain_node_cli_cmd_item_create("ledger", com_ledger, "Ledger info",
+    dap_chain_node_cli_cmd_item_create("ledger", com_ledger, "Ledger information",
             "ledger list coins -net <network name>\n"
-            "ledger list coins_cond -net <network name>\n"
-            "ledger list addrs -net <network name>\n"
-            "ledger tx [all | -addr <addr> | -w <wallet name> | -tx <tx_hash>] [-chain <chain name>] -net <network name>\n");
+            "ledger list threshold -net <network name>\n"
+            "ledger info -hash <tx_hash> -net <network name> [-unspent]\n"
+            "ledger tx -all -net <network name>\n"
+            "ledger tx [-addr <addr> | -w <wallet name> | -tx <tx_hash>] [-chain <chain name>] -net <network name>\n");
 
     // Token info
     dap_chain_node_cli_cmd_item_create("token", com_token, "Token info",
diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c
index 920722cabb..9f3ea16729 100644
--- a/modules/net/dap_chain_node_cli_cmd_tx.c
+++ b/modules/net/dap_chain_node_cli_cmd_tx.c
@@ -775,22 +775,23 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply)
         return -1;
     }
 
+    //switch ledger params list | tx | info
     int l_cmd = CMD_NONE;
-    if (dap_chain_node_cli_find_option_val(a_argv, 1, 2, "list", NULL)){
+    if (dap_chain_node_cli_find_option_val(a_argv, 0, a_argc, "list", NULL)){
         l_cmd = CMD_LIST;
     } else if (dap_chain_node_cli_find_option_val(a_argv, 1, 2, "tx", NULL)){
         l_cmd = CMD_TX_HISTORY;
-        if (dap_chain_node_cli_find_option_val(a_argv, 2, 3, "info", NULL))
-            l_cmd = CMD_TX_INFO;
-    }
+    } else if (dap_chain_node_cli_find_option_val(a_argv, 2, 3, "info", NULL))
+        l_cmd = CMD_TX_INFO; 
+
     // command tx_history
     if(l_cmd == CMD_TX_HISTORY) {
-        bool l_is_all = dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-all", NULL);
-        dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-addr", &l_addr_base58);
-        dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-w", &l_wallet_name);
-        dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-net", &l_net_str);
-        dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-chain", &l_chain_str);
-        dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-tx", &l_tx_hash_str);
+        bool l_is_all = dap_chain_node_cli_find_option_val(a_argv, 0, a_argc, "-all", NULL);
+        dap_chain_node_cli_find_option_val(a_argv, 0, a_argc, "-addr", &l_addr_base58);
+        dap_chain_node_cli_find_option_val(a_argv, 0, a_argc, "-w", &l_wallet_name);
+        dap_chain_node_cli_find_option_val(a_argv, 0, a_argc, "-net", &l_net_str);
+        dap_chain_node_cli_find_option_val(a_argv, 0, a_argc, "-chain", &l_chain_str);
+        dap_chain_node_cli_find_option_val(a_argv, 0, a_argc, "-tx", &l_tx_hash_str);
         dap_chain_tx_hash_processed_ht_t *l_list_tx_hash_processd = NULL;
 
         if(!l_is_all && !l_addr_base58 && !l_wallet_name && !l_tx_hash_str) {
@@ -914,15 +915,17 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply)
         return 0;
     }
     else if(l_cmd == CMD_LIST){
-        enum {SUBCMD_NONE, SUBCMD_LIST_COIN};
+        enum {SUBCMD_NONE, SUBCMD_LIST_COIN, SUB_CMD_LIST_LEDGER_THRESHOLD};
         int l_sub_cmd = SUBCMD_NONE;
         if (dap_chain_node_cli_find_option_val(a_argv, 2, 3, "coins", NULL ))
                 l_sub_cmd = SUBCMD_LIST_COIN;
+        if (dap_chain_node_cli_find_option_val(a_argv, 0, a_argc, "threshold", NULL ))
+                l_sub_cmd = SUB_CMD_LIST_LEDGER_THRESHOLD;
         if (l_sub_cmd == SUBCMD_NONE) {
-            dap_chain_node_cli_set_reply_text(a_str_reply, "Command 'list' requires subcommand 'coins'");
+            dap_chain_node_cli_set_reply_text(a_str_reply, "Command 'list' requires subcommands 'coins' or 'threshold'");
             return -5;
         }
-        dap_chain_node_cli_find_option_val(a_argv, 3, a_argc, "-net", &l_net_str);
+        dap_chain_node_cli_find_option_val(a_argv, 0, a_argc, "-net", &l_net_str);
         if (l_net_str == NULL){
             dap_chain_node_cli_set_reply_text(a_str_reply, "Command 'list' requires key -net");
             return -1;
@@ -932,6 +935,15 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply)
             dap_chain_node_cli_set_reply_text(a_str_reply, "Can't get ledger for net %s", l_net_str);
             return -2;
         }
+        if (l_sub_cmd == SUB_CMD_LIST_LEDGER_THRESHOLD){
+            dap_string_t *l_str_ret = dap_chain_ledger_treshold_info(l_ledger);
+            if (l_str_ret){
+                dap_chain_node_cli_set_reply_text(a_str_reply, l_str_ret->str);
+                dap_string_free(l_str_ret, true);
+            }
+                
+            return 0;
+        }
         dap_string_t *l_str_ret = dap_string_new("");
         dap_list_t *l_token_list = dap_chain_ledger_token_info(l_ledger);
         dap_string_append_printf(l_str_ret, "Found %u tokens in %s ledger\n", dap_list_length(l_token_list), l_net_str);
diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c
index 563c934657..61940eda85 100644
--- a/modules/type/dag/dap_chain_cs_dag.c
+++ b/modules/type/dag/dap_chain_cs_dag.c
@@ -151,7 +151,7 @@ int dap_chain_cs_dag_init(void)
             "\tdoesn't changes after sign add to event. \n\n"
         "dag event dump -net <chain net name> -chain <chain name> -event <event hash> -from < events | events_lasts | round.new  | round.<Round id in hex> > [-H hex|base58(default)]\n"
             "\tDump event info\n\n"
-        "dag event list -net <chain net name> -chain <chain name> -from < events | events_lasts | round.new | round.<Round id in hex> \n\n"
+        "dag event list -net <chain net name> -chain <chain name> -from < events | events_lasts | threshold | round.new | round.<Round id in hex> \n\n"
             "\tShow event list \n\n"
         "dag round complete -net <chain net name> -chain <chain name> \n\n"
                                         "\tComplete the current new round, verify it and if everything is ok - publish new events in chain\n\n"
-- 
GitLab