From 8819e1b43e77c28d6a0e37f7044f54a9e37be60c Mon Sep 17 00:00:00 2001
From: cellframe <roman.khlopkov@demlabs.net>
Date: Thu, 21 Apr 2022 07:40:26 +0300
Subject: [PATCH] [*] tx_history, ledger cmds, math conversion fixes

---
 modules/common/dap_chain_common.c         | 71 +++++++++++++++++------
 modules/common/include/dap_chain_common.h |  6 +-
 modules/net/dap_chain_node_cli_cmd_tx.c   | 28 +++++----
 modules/type/dag/dap_chain_cs_dag.c       |  2 +-
 4 files changed, 71 insertions(+), 36 deletions(-)

diff --git a/modules/common/dap_chain_common.c b/modules/common/dap_chain_common.c
index 2bd20aad98..23e6c5a380 100644
--- a/modules/common/dap_chain_common.c
+++ b/modules/common/dap_chain_common.c
@@ -40,8 +40,8 @@
 /*
  * Forward declarations
  */
-#define DAP_CHAIN$SZ_MAX128DEC 39                                           /* "340282366920938463463374607431768211455" */
-#define DAP_CHAIN$SZ_MAX256DEC (2*39)                                       /* 2 * "340282366920938463463374607431768211455" */
+#define DAP_CHAIN$SZ_MAX128DEC DATOSHI_POW                                           /* "340282366920938463463374607431768211455" */
+#define DAP_CHAIN$SZ_MAX256DEC DATOSHI_POW256                                       /* 2 ^ "340282366920938463463374607431768211455" */
 
 char        *dap_cvt_uint256_to_str (uint256_t a_uint256);
 uint256_t   dap_cvt_str_to_uint256 (const char *a_256bit_num);
@@ -355,20 +355,19 @@ char *dap_chain_balance_to_coins256(uint256_t a_balance)
 
     l_strlen = strlen(l_buf);
 
-    if ( 0 < (l_len = (l_strlen - DATOSHI_DEGREE_18 * 2)) )
+    if ( 0 < (l_len = (l_strlen - DATOSHI_DEGREE)) )
     {
         l_cp = l_buf + l_len;                                               /* Move last 18 symbols to one position right */
-        memmove(l_cp + 1, l_cp, DATOSHI_DEGREE_18 * 2);
+        memmove(l_cp + 1, l_cp, DATOSHI_DEGREE);
         *l_cp = '.';                                                        /* Insert '.' separator */
 
         l_strlen++;                                                         /* Adjust string len in the buffer */
     } else {
-        l_len = DATOSHI_DEGREE_18 * 2 - l_strlen + 2;                           /* Add leading "0." */
+        l_len = DATOSHI_DEGREE - l_strlen;                           /* Add leading "0." */
         l_cp = l_buf;
-        memmove(l_cp + 2, l_cp, l_len);                                     /* Move last 18 symbols to 2 positions right */
-        *(l_cp++) = '0';
-        *(l_cp++) = '.';
-
+        memmove(l_cp + l_len + 2, l_cp, DATOSHI_DEGREE - l_len);                                     /* Move last 18 symbols to 2 positions right */
+        memset(l_cp, '0', l_len + 2);
+        *(++l_cp) = '.';
         l_strlen += 2;                                                      /* Adjust string len in the buffer */
     }
 
@@ -391,7 +390,7 @@ char *dap_chain_balance_to_coins256(uint256_t a_balance)
         l_strlen = l_len;                                                   /* Adjust string len in the buffer */
     }
 
-    for ( l_cp = l_buf + l_strlen -1; *l_cp == '0'; l_cp--)
+    for ( l_cp = l_buf + strlen(l_buf) - 1; *l_cp == '0'; l_cp--)
         if (*(l_cp - 1) != '.')
             *l_cp = '\0';
 
@@ -588,7 +587,7 @@ uint256_t dap_chain_coins_to_balance256(const char *a_coins)
 
     l_pos = l_len - (l_point - l_buf);                                      /* Check number of decimals after dot */
     l_pos--;
-    if ( (l_pos ) >  DATOSHI_DEGREE_18 )
+    if ( (l_pos ) >  DATOSHI_DEGREE )
         return  log_it(L_WARNING, "Incorrect balance format of '%s' - too much precision", l_buf), l_nul;
 
     /* "123.456" -> "123456" */
@@ -604,7 +603,7 @@ uint256_t dap_chain_coins_to_balance256(const char *a_coins)
      *           |            |
      *           +-18 digits--+
      */
-    memset(l_point + l_pos, '0', DATOSHI_DEGREE_18 - l_pos);
+    memset(l_point + l_pos, '0', DATOSHI_DEGREE - l_pos);
 
     return dap_cvt_str_to_uint256 (l_buf);
 }
@@ -736,13 +735,51 @@ const union __c_pow10_double__ {
 
 uint256_t dap_cvt_str_to_uint256(const char *a_256bit_num)
 {
-
-    int l_strlen = strlen(a_256bit_num);
     uint256_t l_ret = uint256_0, l_nul = uint256_0;
-    if (l_strlen > DATOSHI_POW * 2 + 1)
-        return l_nul;
+    int  l_strlen;
+    char l_256bit_num[DAP_CHAIN$SZ_MAX256DEC];
+
+    /* Compute & check length */
+    if ( (l_strlen = strnlen(a_256bit_num, DAP_CHAIN$SZ_MAX256DEC + 1) ) > DAP_CHAIN$SZ_MAX256DEC)
+        return  log_it(L_ERROR, "Too many digits in `%s` (%d > %d)", a_256bit_num, l_strlen, DAP_CHAIN$SZ_MAX256DEC), l_nul;
+
+    /* Convert number from xxx.yyyyE+zz to xxxyyyy0000... */
+    char *l_eptr = strchr(a_256bit_num, 'e');
+    if (!l_eptr)
+        l_eptr = strchr(a_256bit_num, 'E');
+    if (l_eptr) {
+        char *l_exp_ptr = l_eptr + 1;
+        if (*l_exp_ptr == '+')
+            l_exp_ptr++;
+        int l_exp = atoi(l_exp_ptr);
+        if (!l_exp)
+            return  log_it(L_ERROR, "Invalid exponent %s", l_eptr), uint256_0;
+        char *l_dot_ptr = strchr(a_256bit_num, '.');
+        if (!l_dot_ptr || l_dot_ptr > l_eptr)
+            return  log_it(L_ERROR, "Invalid number format with exponent %d", l_exp), uint256_0;
+        int l_dot_len = l_dot_ptr - a_256bit_num;
+        if (l_dot_len >= DAP_CHAIN$SZ_MAX256DEC)
+            return log_it(L_ERROR, "Too many digits in '%s'", a_256bit_num), uint256_0;
+        int l_exp_len = l_eptr - a_256bit_num - l_dot_len - 1;
+        if (l_exp_len + l_dot_len + 1 >= DAP_CHAIN$SZ_MAX256DEC)
+            return log_it(L_ERROR, "Too many digits in '%s'", a_256bit_num), uint256_0;
+        if (l_exp < l_exp_len)
+            return  log_it(L_ERROR, "Invalid number format with exponent %d and nuber coun after dot %d", l_exp, l_exp_len), uint256_0;
+        memcpy(l_256bit_num, a_256bit_num, l_dot_len);
+        memcpy(l_256bit_num + l_dot_len, a_256bit_num + l_dot_len + 1, l_exp_len);
+        int l_zero_cnt = l_exp - l_exp_len;
+        size_t l_pos = l_dot_len + l_exp_len;
+        for (int i = l_zero_cnt; i && l_pos < DAP_CHAIN$SZ_MAX256DEC; i--)
+            l_256bit_num[l_pos++] = '0';
+        l_256bit_num[l_pos] = '\0';
+        l_strlen = l_pos;
+    } else {
+        memcpy(l_256bit_num, a_256bit_num, l_strlen);
+        l_256bit_num[l_strlen] = '\0';
+    }
+
     for (int i = 0; i < l_strlen ; i++) {
-        char c = a_256bit_num[l_strlen - i - 1];
+        char c = l_256bit_num[l_strlen - i - 1];
         if (!isdigit(c)) {
             log_it(L_WARNING, "Incorrect input number");
             return l_nul;
diff --git a/modules/common/include/dap_chain_common.h b/modules/common/include/dap_chain_common.h
index 3c45f11e11..5dae58989a 100644
--- a/modules/common/include/dap_chain_common.h
+++ b/modules/common/include/dap_chain_common.h
@@ -43,10 +43,10 @@
 #define DAP_CHAIN_TIMESTAMP_SIZE    8
 #define DAP_CHAIN_TICKER_SIZE_MAX   10
 
-#define DATOSHI_LD 1000000000.0L
-#define DATOSHI_DEGREE 9
-#define DATOSHI_DEGREE_18   18
+#define DATOSHI_LD 1000000000.0L    // Deprecated
+#define DATOSHI_DEGREE 18
 #define DATOSHI_POW 38
+#define DATOSHI_POW256 (DATOSHI_POW * 2)
 
 // Chain ID of the whole system
 typedef union dap_chain_id {
diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c
index c7470c7655..104ce052a5 100644
--- a/modules/net/dap_chain_node_cli_cmd_tx.c
+++ b/modules/net/dap_chain_node_cli_cmd_tx.c
@@ -95,13 +95,7 @@ static bool s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum,
 {
     const char *l_ticker = NULL;
     if (a_ledger) {
-        dap_list_t *l_list_tx_any = dap_chain_datum_tx_items_get(a_datum, TX_ITEM_TYPE_TOKEN, NULL);
-        if (l_list_tx_any) {
-            l_ticker = ((dap_chain_tx_token_t*)l_list_tx_any->data)->header.ticker;
-        } else {
             l_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(a_ledger, a_tx_hash);
-        }
-        dap_list_free(l_list_tx_any);
         if (!l_ticker)
             return false;
     }
@@ -463,13 +457,13 @@ char* dap_db_history_addr(dap_chain_addr_t * a_addr, dap_chain_t * a_chain, cons
                 strncpy(l_tx_data->token_ticker, l_tx_data_prev->token_ticker, DAP_CHAIN_TICKER_SIZE_MAX);
 
                 dap_chain_datum_tx_t *l_tx_prev;
-                dap_list_t *l_list_prev_out_items, *l_list_out_prev_item;
+                dap_list_t *l_list_prev_out_items = NULL, *l_list_out_prev_item;
 
                 if ( (l_tx_prev = (dap_chain_datum_tx_t *)l_tx_data_prev->datum->data) )
-                    if ( (l_list_prev_out_items = dap_chain_datum_tx_items_get(l_tx_prev, TX_ITEM_TYPE_OUT_OLD, NULL)) )
+                    if ( (l_list_prev_out_items = dap_chain_datum_tx_items_get(l_tx_prev, TX_ITEM_TYPE_OUT, NULL)) )
                         if ( (l_list_out_prev_item = dap_list_nth(l_list_prev_out_items, l_tx_in->header.tx_out_prev_idx)) )
                             {
-                            l_src_addr = &((dap_chain_tx_out_old_t *)l_list_out_prev_item->data)->addr;
+                            l_src_addr = &((dap_chain_tx_out_t *)l_list_out_prev_item->data)->addr;
                             l_src_addr_str = dap_chain_addr_to_str(l_src_addr);
                             }
 
@@ -497,9 +491,9 @@ char* dap_db_history_addr(dap_chain_addr_t * a_addr, dap_chain_t * a_chain, cons
 
             // find OUT items
             bool l_header_printed = false;
-            dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_OLD, NULL);
+            dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT, NULL);
             for (dap_list_t *l_list_out = l_list_out_items; l_list_out; l_list_out = dap_list_next(l_list_out)) {
-                dap_chain_tx_out_old_t *l_tx_out = (dap_chain_tx_out_old_t *)l_list_out->data;
+                dap_chain_tx_out_t *l_tx_out = (dap_chain_tx_out_t *)l_list_out->data;
                 if (l_src_addr && !memcmp(&l_tx_out->addr, l_src_addr, sizeof(dap_chain_addr_t)))
                     continue;   // send to self
                 if (l_src_addr && !memcmp(l_src_addr, a_addr, sizeof(dap_chain_addr_t))) {
@@ -508,21 +502,25 @@ char* dap_db_history_addr(dap_chain_addr_t * a_addr, dap_chain_t * a_chain, cons
                         l_header_printed = true;
                     }
                     char *l_dst_addr_str = dap_chain_addr_to_str(&l_tx_out->addr);
-                    dap_string_append_printf(l_str_out, "\tsend %"DAP_UINT64_FORMAT_U" %s to %s\n",
-                                             l_tx_out->header.value,
+                    char *l_value_str = dap_chain_balance_print(l_tx_out->header.value);
+                    dap_string_append_printf(l_str_out, "\tsend %s %s to %s\n",
+                                             l_value_str,
                                              l_tx_data->token_ticker,
                                              l_dst_addr_str);
                     DAP_DELETE(l_dst_addr_str);
+                    DAP_DELETE(l_value_str);
                 }
                 if (!memcmp(&l_tx_out->addr, a_addr, sizeof(dap_chain_addr_t))) {
                     if (!l_header_printed) {
                         dap_string_append_printf(l_str_out, "TX hash %s\n\t%s", l_tx_hash_str, l_time_str);
                         l_header_printed = true;
                     }
-                    dap_string_append_printf(l_str_out, "\trecv %"DAP_UINT64_FORMAT_U" %s from %s\n",
-                                             l_tx_out->header.value,
+                    char *l_value_str = dap_chain_balance_print(l_tx_out->header.value);
+                    dap_string_append_printf(l_str_out, "\trecv %s %s from %s\n",
+                                             l_value_str,
                                              l_tx_data->token_ticker,
                                              l_src_addr ? l_src_addr_str : "emission");
+                    DAP_DELETE(l_value_str);
                 }
             }
             dap_list_free(l_list_out_items);
diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c
index ec73d49ad7..7acbd84f40 100644
--- a/modules/type/dag/dap_chain_cs_dag.c
+++ b/modules/type/dag/dap_chain_cs_dag.c
@@ -1278,7 +1278,7 @@ static dap_chain_atom_ptr_t s_chain_callback_atom_iter_get_next( dap_chain_atom_
             break;
     }
 
-    if(!l_event_item && !a_atom_iter->found_in_treshold) {
+    if(!l_event_item && !a_atom_iter->found_in_treshold && a_atom_iter->with_treshold) {
         dap_chain_cs_dag_t *l_dag = DAP_CHAIN_CS_DAG(a_atom_iter->chain);
         assert(l_dag);
         dap_chain_cs_dag_pvt_t *l_dag_pvt = PVT(l_dag);
-- 
GitLab